ZQuest Classic Coverage Report


Directory: src/
File: src/zc/maps.cpp
Date: 2025-11-02 08:20:44
Exec Total Coverage
Lines: 4199 5226 80.3%
Functions: 295 333 88.6%
Branches: 3251 5308 61.2%

Line Branch Exec Source
1 #include "base/combo.h"
2 #include "base/handles.h"
3 #include "base/util.h"
4 #include "base/zdefs.h"
5 #include "base/general.h"
6 #include <cstring>
7 #include <assert.h>
8 #include <math.h>
9 #include <vector>
10 #include <deque>
11 #include <string>
12 #include <set>
13 #include <array>
14 #include <sstream>
15 using std::set;
16
17 #include "base/qrs.h"
18 #include "base/dmap.h"
19 #include "base/mapscr.h"
20 #include "base/misctypes.h"
21 #include "base/initdata.h"
22 #include "zc/maps.h"
23 #include "zc/zelda.h"
24 #include "zc/zc_ffc.h"
25 #include "tiles.h"
26 #include "sprite.h"
27 #include "gui/jwin.h"
28 #include "base/zsys.h"
29 #include "subscr.h"
30 #include "zc/zc_subscr.h"
31 #include "zc/hero.h"
32 #include "zc/guys.h"
33 #include "zc/ffscript.h"
34 #include "drawing.h"
35 #include "zc/combos.h"
36 #include "zc/replay.h"
37 #include "slopes.h"
38 #include "particles.h"
39 #include <fmt/format.h>
40 #include "zc/render.h"
41 #include "iter.h"
42 #include <ranges>
43
44 // All the temporary screens (and their layers) for the currently loaded map.
45 static mapscr* temporary_screens[136*7];
46 // Set by load_region.
47 static bool screen_in_current_region[136];
48 427 static rpos_handle_t current_region_rpos_handles[136*7];
49 static bool current_region_rpos_handles_dirty;
50 static int current_region_screen_count;
51 static std::pair<const rpos_handle_t*, int> current_region_rpos_handles_scr[136];
52
53 viewport_t viewport;
54 static int viewport_sprite_uid;
55 ViewportMode viewport_mode;
56 int world_w, world_h;
57 int region_scr_dx, region_scr_dy;
58 int region_scr_count;
59 rpos_t region_max_rpos;
60 int region_num_rpos;
61 region_t cur_region, scrolling_region;
62
63 427 maze_state_t maze_state;
64 int scrolling_maze_last_solved_screen;
65
66 608 void maps_init_game_vars()
67 {
68 608 viewport = {};
69 608 viewport_mode = ViewportMode::CenterAndBound;
70 608 viewport_sprite_uid = 1;
71 608 currscr_for_passive_subscr = -1;
72 608 }
73
74 static region_ids_t current_region_ids;
75
76 // Returns true if the (map, screen) is inside a scrolling region.
77 15147313 static bool is_in_scrolling_region(int map, int screen)
78 {
79 15147313 return get_region_id(map, screen) != 0;
80 }
81
82 bool is_in_screenscrolling_region(int screen)
83 {
84 if (!screenscrolling) return false;
85
86 int x = screen % 16;
87 int y = screen / 16;
88 return
89 scrolling_region.origin_screen_x >= x && scrolling_region.origin_screen_x < x + scrolling_region.screen_width &&
90 scrolling_region.origin_screen_y >= y && scrolling_region.origin_screen_y < y + scrolling_region.screen_height;
91 }
92
93 9003604541 bool is_in_scrolling_region()
94 {
95 9003604541 return cur_region.screen_count > 1;
96 }
97
98 2232 static bool is_same_region_id(int region_origin_scr, int map, int scr)
99 {
100
2/2
✓ Branch 0 taken 772 times.
✓ Branch 1 taken 1460 times.
2232 if (!is_in_scrolling_region(map, scr)) return false;
101 1460 int region_id = get_region_id(map, region_origin_scr);
102
1/2
✓ Branch 0 taken 1460 times.
✗ Branch 1 not taken.
1460 return region_id && region_id == get_region_id(map, scr);
103 2232 }
104
105 251314017 bool is_in_current_region(int map, int screen)
106 {
107
2/2
✓ Branch 0 taken 1598 times.
✓ Branch 1 taken 251312419 times.
251314017 if (map != cur_map)
108 1598 return false;
109
110
3/4
✓ Branch 0 taken 251312419 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 251300206 times.
✓ Branch 3 taken 12213 times.
251312419 if (screen >= 0 && screen < 128)
111 251300206 return screen_in_current_region[screen];
112
113 12213 return screen == cur_screen;
114 251314017 }
115
116 244730872 bool is_in_current_region(int screen)
117 {
118
5/6
✓ Branch 0 taken 243615254 times.
✓ Branch 1 taken 1115618 times.
✓ Branch 2 taken 1115618 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 5 times.
✓ Branch 5 taken 1115613 times.
244730872 return screen == cur_screen || (screen >= 0 && screen < 128 && screen_in_current_region[screen]);
119 }
120
121 30764985 bool is_in_current_region(mapscr* scr)
122 {
123
2/2
✓ Branch 0 taken 14690 times.
✓ Branch 1 taken 30750295 times.
30764985 return scr->map == cur_map && is_in_current_region(scr->screen);
124 }
125
126 63777627 bool is_extended_height_mode()
127 {
128
2/2
✓ Branch 0 taken 63578179 times.
✓ Branch 1 taken 199448 times.
63777627 return cur_region.screen_height > 1 && (DMaps[cur_dmap].flags & dmfEXTENDEDVIEWPORT);
129 }
130
131 // Returns 0 if this is not a scrolling region.
132 42486105 int get_region_id(int map, int screen)
133 {
134
2/2
✓ Branch 0 taken 401435 times.
✓ Branch 1 taken 42084670 times.
42486105 if (screen >= 128) return 0;
135
2/2
✓ Branch 0 taken 42083546 times.
✓ Branch 1 taken 1124 times.
42084670 if (map == cur_region.map) return current_region_ids[screen];
136
137 1124 return Regions[map].get_region_id(screen);
138 42486105 }
139
140 27276802 int get_current_region_id()
141 {
142 27276802 return get_region_id(cur_map, cur_screen);
143 }
144
145 67244 void calculate_region(int map, int screen, region_t& region, int& region_scr_dx, int& region_scr_dy)
146 {
147 67244 region.map = map;
148
149
2/2
✓ Branch 0 taken 66970 times.
✓ Branch 1 taken 274 times.
67244 if (!is_in_scrolling_region(map, screen))
150 {
151 66970 region.region_id = 0;
152 66970 region.origin_screen = screen;
153 66970 region.origin_screen_x = screen % 16;
154 66970 region.origin_screen_y = screen / 16;
155 66970 region.screen_width = 1;
156 66970 region.screen_height = 1;
157 66970 region.screen_count = 1;
158 66970 region.width = 256;
159 66970 region.height = 176;
160 66970 region_scr_dx = 0;
161 66970 region_scr_dy = 0;
162 66970 return;
163 }
164
165 274 int input_scr_x = screen % 16;
166 274 int input_scr_y = screen / 16;
167
168 // For the given screen, find the top-left corner of its region.
169 274 int origin_scr_x = input_scr_x;
170 274 int origin_scr_y = input_scr_y;
171 274 int origin_scr = screen;
172
2/2
✓ Branch 0 taken 62 times.
✓ Branch 1 taken 372 times.
434 while (origin_scr_x > 0)
173 {
174
2/2
✓ Branch 0 taken 212 times.
✓ Branch 1 taken 160 times.
372 if (!is_same_region_id(origin_scr, map, map_scr_xy_to_index(origin_scr_x - 1, origin_scr_y))) break;
175 160 origin_scr_x--;
176 }
177
2/2
✓ Branch 0 taken 94 times.
✓ Branch 1 taken 414 times.
508 while (origin_scr_y > 0)
178 {
179
2/2
✓ Branch 0 taken 180 times.
✓ Branch 1 taken 234 times.
414 if (!is_same_region_id(origin_scr, map, map_scr_xy_to_index(origin_scr_x, origin_scr_y - 1))) break;
180 234 origin_scr_y--;
181 }
182 274 origin_scr = map_scr_xy_to_index(origin_scr_x, origin_scr_y);
183
184 // Now find the bottom-right corner.
185 274 int region_scr_right = origin_scr_x;
186
2/2
✓ Branch 0 taken 28 times.
✓ Branch 1 taken 614 times.
642 while (region_scr_right < 15)
187 {
188
2/2
✓ Branch 0 taken 246 times.
✓ Branch 1 taken 368 times.
614 if (!is_same_region_id(origin_scr, map, map_scr_xy_to_index(region_scr_right + 1, origin_scr_y))) break;
189 368 region_scr_right++;
190 }
191 274 int region_scr_bottom = origin_scr_y;
192
2/2
✓ Branch 0 taken 24 times.
✓ Branch 1 taken 832 times.
856 while (region_scr_bottom < 7)
193 {
194
2/2
✓ Branch 0 taken 250 times.
✓ Branch 1 taken 582 times.
832 if (!is_same_region_id(origin_scr, map, map_scr_xy_to_index(origin_scr_x, region_scr_bottom + 1))) break;
195 582 region_scr_bottom++;
196 }
197
198 274 region.region_id = get_region_id(map, origin_scr);
199 274 region.origin_screen = origin_scr;
200 274 region.origin_screen_x = origin_scr_x;
201 274 region.origin_screen_y = origin_scr_y;
202 274 region.screen_width = region_scr_right - origin_scr_x + 1;
203 274 region.screen_height = region_scr_bottom - origin_scr_y + 1;
204 274 region.screen_count = region.screen_width * region.screen_height;
205 274 region.width = 256 * region.screen_width;
206 274 region.height = 176 * region.screen_height;
207 274 region_scr_dx = input_scr_x - origin_scr_x;
208 274 region_scr_dy = input_scr_y - origin_scr_y;
209
210 DCHECK_RANGE_INCLUSIVE(region.screen_width, 0, 16);
211 DCHECK_RANGE_INCLUSIVE(region.screen_height, 0, 8);
212 67244 }
213
214 37530 void load_region(int dmap, int screen)
215 {
216 37530 clear_temporary_screens();
217
218 37530 int map = DMaps[dmap].map;
219 37530 current_region_ids = Regions[map].get_all_region_ids();
220
221 37530 calculate_region(map, screen, cur_region, region_scr_dx, region_scr_dy);
222 37530 cur_screen = cur_region.origin_screen;
223 37530 world_w = cur_region.width;
224 37530 world_h = cur_region.height;
225 37530 region_scr_count = cur_region.screen_count;
226 37530 region_max_rpos = (rpos_t)(cur_region.screen_count*176 - 1);
227 37530 region_num_rpos = cur_region.screen_count*176;
228 37530 scrolling_maze_last_solved_screen = 0;
229
230 37530 memset(screen_in_current_region, false, sizeof(screen_in_current_region));
231
2/2
✓ Branch 0 taken 37764 times.
✓ Branch 1 taken 37530 times.
75294 for (int x = 0; x < cur_region.screen_width; x++)
232 {
233
2/2
✓ Branch 0 taken 38774 times.
✓ Branch 1 taken 37764 times.
76538 for (int y = 0; y < cur_region.screen_height; y++)
234 {
235 38774 int screen = cur_screen + x + y*16;
236
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 38774 times.
38774 if (screen < 136)
237 {
238 38774 screen_in_current_region[screen] = true;
239 38774 }
240 38774 }
241 37764 }
242
243 37530 mark_current_region_handles_dirty();
244 37530 }
245
246 37530 static void prepare_current_region_handles()
247 {
248 37530 current_region_rpos_handles_dirty = false;
249 37530 current_region_screen_count = 0;
250
2/2
✓ Branch 0 taken 37878 times.
✓ Branch 1 taken 37530 times.
75408 for (int y = 0; y < cur_region.screen_height; y++)
251 {
252
2/2
✓ Branch 0 taken 38774 times.
✓ Branch 1 taken 37878 times.
76652 for (int x = 0; x < cur_region.screen_width; x++)
253 {
254 38774 int screen = cur_screen + x + y*16;
255 38774 int index_start = current_region_screen_count;
256
2/2
✓ Branch 0 taken 38774 times.
✓ Branch 1 taken 271418 times.
310192 for (int layer = 0; layer <= 6; layer++)
257 {
258 271418 mapscr* scr = get_scr_layer(screen, layer);
259
2/2
✓ Branch 0 taken 95243 times.
✓ Branch 1 taken 176175 times.
271418 if (!scr->is_valid())
260 {
261
1/2
✓ Branch 0 taken 176175 times.
✗ Branch 1 not taken.
176175 if (layer == 0) break;
262 176175 continue;
263 }
264
265 95243 rpos_t base_rpos = POS_TO_RPOS(0, get_region_relative_dx(screen), get_region_relative_dy(screen));
266 95243 current_region_rpos_handles[current_region_screen_count] = {scr, screen, layer, base_rpos, 0};
267 95243 current_region_screen_count += 1;
268 95243 }
269
270 38774 int num_handles_for_scr = current_region_screen_count - index_start;
271 38774 current_region_rpos_handles_scr[screen] = {&current_region_rpos_handles[index_start], num_handles_for_scr};
272 38774 }
273 37878 }
274 37530 }
275
276 1814650487 std::tuple<const rpos_handle_t*, int> get_current_region_handles()
277 {
278 DCHECK(!current_region_rpos_handles_dirty);
279 1814650487 return {current_region_rpos_handles, current_region_screen_count};
280 }
281
282 11481640 std::tuple<const rpos_handle_t*, int> get_current_region_handles(mapscr* scr)
283 {
284 DCHECK(!current_region_rpos_handles_dirty);
285
2/4
✓ Branch 0 taken 11481640 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 11481640 times.
11481640 if (scr == special_warp_return_scr || current_region_rpos_handles_dirty)
286 return {nullptr, 0};
287
288
2/2
✓ Branch 0 taken 65877 times.
✓ Branch 1 taken 11415763 times.
11481640 if (cur_screen >= 0x80)
289 {
290 DCHECK(scr == origin_scr);
291 65877 return {nullptr, 0};
292 }
293
294 DCHECK(is_in_current_region(scr));
295 11415763 return current_region_rpos_handles_scr[scr->screen];
296 11481640 }
297
298 37530 void mark_current_region_handles_dirty()
299 {
300 37530 current_region_rpos_handles_dirty = true;
301 37530 }
302
303 68003 void delete_temporary_screens(mapscr** screens)
304 {
305
2/2
✓ Branch 0 taken 64738856 times.
✓ Branch 1 taken 68003 times.
64806859 for (int i = 0; i < 136*7; i++)
306 {
307
2/2
✓ Branch 0 taken 267351 times.
✓ Branch 1 taken 64471505 times.
64738856 if (!screens[i])
308 64471505 continue;
309
310 267351 mapscr* scr = screens[i];
311 267351 int num_ffcs = scr->numFFC();
312
2/2
✓ Branch 0 taken 7621503 times.
✓ Branch 1 taken 267351 times.
7888854 for (int i = 0; i < num_ffcs; i++)
313 {
314 7621503 sprite* ffc = &scr->ffcs[i];
315
2/2
✓ Branch 0 taken 7617968 times.
✓ Branch 1 taken 3535 times.
7621503 if (ffc->uid)
316 3535 FFCore.release_sprite_owned_objects(ffc->uid);
317 7621503 }
318
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 267351 times.
267351 delete scr;
319 267351 screens[i] = NULL;
320 267351 }
321 68003 }
322
323 38700 void clear_temporary_screens()
324 {
325 38700 delete_temporary_screens(temporary_screens);
326 38700 origin_scr = nullptr;
327 38700 hero_scr = nullptr;
328 38700 }
329
330 29307 std::vector<mapscr*> take_temporary_scrs()
331 {
332
1/2
✓ Branch 0 taken 29307 times.
✗ Branch 1 not taken.
29307 std::vector<mapscr*> screens(temporary_screens, temporary_screens + 136*7);
333
2/2
✓ Branch 0 taken 29307 times.
✓ Branch 1 taken 27900264 times.
27929571 for (int i = 0; i < 136*7; i++)
334 27900264 temporary_screens[i] = nullptr;
335
336 29307 return screens;
337
1/2
✓ Branch 0 taken 29307 times.
✗ Branch 1 not taken.
29307 }
338
339 15078197 void calculate_viewport(viewport_t& viewport, int dmap, int screen, int world_w, int world_h, int x, int y)
340 {
341 // TODO: In future, maybe add x/y centering offsets to zscript (Viewport->TargetXOffset/Viewport->TargetYOffset).
342
343
2/2
✓ Branch 0 taken 15031615 times.
✓ Branch 1 taken 46582 times.
15078197 bool extended_height_mode = (DMaps[dmap].flags & dmfEXTENDEDVIEWPORT) && world_h > 176;
344 15078197 viewport.w = 256;
345 15078197 viewport.h = 176 + (extended_height_mode ? 56 : 0);
346
347
2/2
✓ Branch 0 taken 360 times.
✓ Branch 1 taken 15077837 times.
15078197 if (viewport_mode == ViewportMode::Script)
348 360 return;
349
350
2/2
✓ Branch 0 taken 46162 times.
✓ Branch 1 taken 15031675 times.
15077837 if (!is_in_scrolling_region(DMaps[dmap].map, screen))
351 {
352 15031675 viewport.x = 0;
353 15031675 viewport.y = 0;
354 15031675 }
355
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 46162 times.
46162 else if (viewport_mode == ViewportMode::CenterAndBound)
356 {
357 // Clamp the viewport to the edges of the region.
358
6/6
✓ Branch 0 taken 8568 times.
✓ Branch 1 taken 37594 times.
✓ Branch 2 taken 6788 times.
✓ Branch 3 taken 39374 times.
✓ Branch 4 taken 8568 times.
✓ Branch 5 taken 30806 times.
46162 viewport.x = CLAMP(0, world_w - viewport.w, x - viewport.w/2);
359
6/6
✓ Branch 0 taken 11856 times.
✓ Branch 1 taken 34306 times.
✓ Branch 2 taken 5650 times.
✓ Branch 3 taken 40512 times.
✓ Branch 4 taken 11856 times.
✓ Branch 5 taken 28656 times.
46162 viewport.y = CLAMP(0, world_h - viewport.h, y - viewport.h/2);
360 46162 }
361 else if (viewport_mode == ViewportMode::Center)
362 {
363 viewport.x = x - viewport.w/2;
364 viewport.y = y - viewport.h/2;
365 }
366 15078197 }
367
368 15077686 sprite* get_viewport_sprite()
369 {
370 15077686 sprite* spr = sprite::getByUID(viewport_sprite_uid);
371
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 15077680 times.
15077686 if (!spr)
372 {
373 6 viewport_sprite_uid = 1; // Hero uid.
374 6 spr = &Hero;
375 6 }
376
377 15077686 return spr;
378 }
379
380 6 void set_viewport_sprite(sprite* spr)
381 {
382 6 viewport_sprite_uid = spr->uid;
383 6 }
384
385 15048379 void update_viewport()
386 {
387 15048379 sprite* spr = get_viewport_sprite();
388 15048379 int x = spr->x + spr->txsz*16/2;
389 15048379 int y = spr->y + spr->tysz*16/2;
390 15048379 calculate_viewport(viewport, cur_dmap, cur_screen, world_w, world_h, x, y);
391 15048379 }
392
393 // TODO: should add a moveflag to sprites to configure the size of this rect (or effectively disable
394 // freezing if the rect returns is large enough). See:
395 // https://discord.com/channels/876899628556091432/1358483603700449581
396 // https://discord.com/channels/876899628556091432/1130384911983980554
397 //
398 89026252 viewport_t get_sprite_freeze_rect()
399 {
400 89026252 viewport_t freeze_rect = viewport;
401 89026252 int tile_buffer = 3;
402 89026252 freeze_rect.w += 16 * tile_buffer * 2;
403 89026252 freeze_rect.h += 16 * tile_buffer * 2;
404 89026252 freeze_rect.x -= 16 * tile_buffer;
405 89026252 freeze_rect.y -= 16 * tile_buffer;
406 89026252 return freeze_rect;
407 }
408
409 4722 mapscr* determine_hero_screen_from_coords()
410 {
411 4722 int x = vbound(Hero.getX().getInt(), 0, world_w - 1);
412 4722 int y = vbound(Hero.getY().getInt(), 0, world_h - 1);
413 4722 int dx = x / 256;
414 4722 int dy = y / 176;
415 4722 return get_scr(cur_screen + dx + dy * 16);
416 }
417
418 28218 bool edge_of_region(direction dir)
419 {
420
2/2
✓ Branch 0 taken 28138 times.
✓ Branch 1 taken 80 times.
28218 if (!is_in_scrolling_region()) return true;
421
422 80 int screen_x = Hero.current_screen % 16;
423 80 int screen_y = Hero.current_screen / 16;
424
2/2
✓ Branch 0 taken 78 times.
✓ Branch 1 taken 2 times.
80 if (dir == up) screen_y -= 1;
425
2/2
✓ Branch 0 taken 70 times.
✓ Branch 1 taken 10 times.
80 if (dir == down) screen_y += 1;
426
2/2
✓ Branch 0 taken 50 times.
✓ Branch 1 taken 30 times.
80 if (dir == left) screen_x -= 1;
427
2/2
✓ Branch 0 taken 42 times.
✓ Branch 1 taken 38 times.
80 if (dir == right) screen_x += 1;
428
4/8
✓ Branch 0 taken 80 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 80 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 80 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 80 times.
✗ Branch 7 not taken.
80 if (screen_x < 0 || screen_x > 16 || screen_y < 0 || screen_y > 8) return true;
429 80 return !is_in_current_region(map_scr_xy_to_index(screen_x, screen_y));
430 28218 }
431
432 // x, y are world coordinates (aka, in relation to origin screen at the top-left).
433 // Coordinates are clamped to the world bounds.
434 338082790 int get_screen_for_world_xy(int x, int y)
435 {
436
2/2
✓ Branch 0 taken 316943766 times.
✓ Branch 1 taken 21139024 times.
338082790 if (!is_in_scrolling_region())
437 316943766 return cur_screen;
438
439 21139024 int dx = std::clamp(x, 0, world_w - 1) / 256;
440 21139024 int dy = std::clamp(y, 0, world_h - 1) / 176;
441 21139024 int origin_screen_x = cur_screen % 16;
442 21139024 int origin_screen_y = cur_screen / 16;
443 21139024 int scr_x = origin_screen_x + dx;
444 21139024 int scr_y = origin_screen_y + dy;
445 21139024 return map_scr_xy_to_index(scr_x, scr_y);
446 338082790 }
447
448 31102071 int get_screen_for_rpos(rpos_t rpos)
449 {
450 31102071 int origin_screen_x = cur_screen % 16;
451 31102071 int origin_screen_y = cur_screen / 16;
452 31102071 int screen = static_cast<int32_t>(rpos) / 176;
453 31102071 int scr_x = origin_screen_x + screen%cur_region.screen_width;
454 31102071 int scr_y = origin_screen_y + screen/cur_region.screen_width;
455 31102071 return map_scr_xy_to_index(scr_x, scr_y);
456 }
457
458 837233820 rpos_handle_t get_rpos_handle(rpos_t rpos, int layer)
459 {
460 DCHECK_LAYER_ZERO_INDEX(layer);
461
2/2
✓ Branch 0 taken 806269712 times.
✓ Branch 1 taken 30964108 times.
837233820 if (!is_in_scrolling_region())
462 806269712 return {get_scr_layer(cur_screen, layer), cur_screen, layer, rpos, RPOS_TO_POS(rpos)};
463 30964108 int screen = get_screen_for_rpos(rpos);
464 30964108 mapscr* scr = get_scr_layer(screen, layer);
465 30964108 return {scr, screen, layer, rpos, RPOS_TO_POS(rpos)};
466 837233820 }
467
468 // x, y are world coordinates (aka, in relation to origin screen at the top-left).
469 // Coordinates are clamped to the world bounds.
470 3484863037 rpos_handle_t get_rpos_handle_for_world_xy(int x, int y, int layer)
471 {
472 3484863037 x = std::clamp(x, 0, world_w - 1);
473 3484863037 y = std::clamp(y, 0, world_h - 1);
474
475 DCHECK_LAYER_ZERO_INDEX(layer);
476
2/2
✓ Branch 0 taken 3458520559 times.
✓ Branch 1 taken 26342478 times.
3484863037 if (!is_in_scrolling_region())
477 {
478 3458520559 int pos = COMBOPOS(x, y);
479 3458520559 return {get_scr_layer(cur_screen, layer), cur_screen, layer, (rpos_t)pos, pos};
480 }
481 26342478 return get_rpos_handle(COMBOPOS_REGION(x, y), layer);
482 3484863037 }
483
484 // Return a rpos_handle_t for a screen-specific `pos` (0-175).
485 1926 rpos_handle_t get_rpos_handle_for_screen(int screen, int layer, int pos)
486 {
487 DCHECK_LAYER_ZERO_INDEX(layer);
488 1926 return {get_scr_layer(screen, layer), screen, layer, POS_TO_RPOS(pos, screen), pos};
489 }
490
491 // Return a rpos_handle_t for a screen-specific `pos` (0-175).
492 // Use this instead of the other `get_pos_handle_for_screen` if you already have a reference to the screen.
493 63140 rpos_handle_t get_rpos_handle_for_scr(mapscr* scr, int layer, int pos)
494 {
495 DCHECK_LAYER_ZERO_INDEX(layer);
496 63140 return {scr, scr->screen, layer, POS_TO_RPOS(pos, scr->screen), pos};
497 }
498
499 25583511 void change_rpos_handle_layer(rpos_handle_t& rpos_handle, int layer)
500 {
501 DCHECK_LAYER_ZERO_INDEX(layer);
502 25583511 rpos_handle.layer = layer;
503 25583511 rpos_handle.scr = get_scr_layer(rpos_handle.screen, layer);
504 25583511 }
505
506 // x, y are world coordinates (aka, in relation to origin screen at the top-left).
507 // Coordinates are clamped to the world bounds.
508 86712 combined_handle_t get_combined_handle_for_world_xy(int x, int y, int layer)
509 {
510 DCHECK_LAYER_ZERO_INDEX(layer);
511
512 86712 x = std::clamp(x, 0, world_w - 1);
513 86712 y = std::clamp(y, 0, world_h - 1);
514
515 86712 auto maybe_ffc_handle = getFFCAt(x, y);
516
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 86712 times.
86712 if (maybe_ffc_handle)
517 return maybe_ffc_handle.value();
518
519 86712 auto rpos = COMBOPOS_REGION_B(x, y);
520
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 86712 times.
86712 if (rpos == rpos_t::None)
521 return rpos_handle_t();
522 86712 return get_rpos_handle(rpos, layer);
523 86712 }
524
525 // These functions all return _temporary_ screens. Any modifications made to them (either by the engine
526 // directly or via zscript) only last until the next area is loaded (via loadscr).
527
528 // Returns the screen containing the (x, y) world position.
529 1555152732 mapscr* get_scr_for_world_xy(int x, int y)
530 {
531 // Quick path, but should work the same without.
532
2/2
✓ Branch 0 taken 1544713332 times.
✓ Branch 1 taken 10439400 times.
1555152732 if (!is_in_scrolling_region()) return origin_scr;
533 10439400 return get_scr(get_screen_for_world_xy(x, y));
534 1555152732 }
535
536 25996662 mapscr* get_scr_for_rpos(rpos_t rpos)
537 {
538 // Quick path, but should work the same without.
539
2/2
✓ Branch 0 taken 25858716 times.
✓ Branch 1 taken 137946 times.
25996662 if (!is_in_scrolling_region()) return origin_scr;
540 137946 return get_scr(get_screen_for_rpos(rpos));
541 25996662 }
542
543 17 mapscr* get_scr_for_rpos_layer(rpos_t rpos, int layer)
544 {
545 17 return get_scr_layer(get_screen_for_rpos(rpos), layer);
546 }
547
548 // Note: layer=0 is the base screen, 1 is the first layer, etc.
549 2135472209 mapscr* get_scr_for_world_xy_layer(int x, int y, int layer)
550 {
551 DCHECK_LAYER_ZERO_INDEX(layer);
552
2/2
✓ Branch 0 taken 2125426995 times.
✓ Branch 1 taken 10045214 times.
2135472209 if (!is_in_scrolling_region()) return get_scr_layer(cur_screen, layer);
553
2/2
✓ Branch 0 taken 708934 times.
✓ Branch 1 taken 9336280 times.
10045214 return layer == 0 ?
554 708934 get_scr_for_world_xy(x, y) :
555 9336280 get_scr_layer(get_screen_for_world_xy(x, y), layer);
556 2135472209 }
557
558 1857305433 int get_region_screen_offset(int screen)
559 {
560 1857305433 return get_region_relative_dx(screen) + get_region_relative_dy(screen) * cur_region.screen_width;
561 }
562
563 655240230 int get_screen_for_region_index_offset(int offset)
564 {
565 655240230 int scr_dx = offset % cur_region.screen_width;
566 655240230 int scr_dy = offset / cur_region.screen_width;
567 655240230 int screen = cur_screen + scr_dx + scr_dy*16;
568 655240230 return screen;
569 }
570
571 655056392 mapscr* get_scr_for_region_index_offset(int offset)
572 {
573 655056392 int screen = get_screen_for_region_index_offset(offset);
574 655056392 return get_scr(screen);
575 }
576
577 // The screen at (map, screen) must exist.
578 1540962626 mapscr* get_scr(int map, int screen)
579 {
580 1540962626 mapscr* scr = get_scr_maybe(map, screen);
581
1/2
✓ Branch 0 taken 1540962626 times.
✗ Branch 1 not taken.
1540962626 CHECK(scr);
582 1540962626 return scr;
583 }
584
585 841466837 mapscr* get_scr(int screen)
586 {
587 841466837 return get_scr(cur_map, screen);
588 }
589
590 // Returns null if active screen does not exist.
591 1726796636 mapscr* get_scr_maybe(int map, int screen)
592 {
593 DCHECK_RANGE_INCLUSIVE(screen, 0, 135);
594
595
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1726796636 times.
1726796636 if (map == cur_map)
596 {
597
2/2
✓ Branch 0 taken 1705970662 times.
✓ Branch 1 taken 20825974 times.
1726796636 if (screen == cur_screen)
598 1705970662 return origin_scr;
599
600 20825974 int index = screen*7;
601
2/2
✓ Branch 0 taken 20802272 times.
✓ Branch 1 taken 23702 times.
20825974 if (temporary_screens[index])
602 20802272 return temporary_screens[index];
603
604
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 23702 times.
23702 if (screen == home_screen)
605 return special_warp_return_scr;
606 23702 }
607
608
4/6
✓ Branch 0 taken 23700 times.
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 23700 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 23700 times.
23702 if (screenscrolling && map == scrolling_map && !FFCore.ScrollingScreensAll.empty())
609 {
610 23700 int index = screen*7;
611
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 23700 times.
23700 if (FFCore.ScrollingScreensAll[index])
612 23700 return FFCore.ScrollingScreensAll[index];
613 }
614
615 2 return nullptr;
616 1726796636 }
617
618 // Note: layer=0 returns the base screen, layer=1 returns the first layer.
619 6986677251 mapscr* get_scr_layer(int map, int screen, int layer)
620 {
621 DCHECK_LAYER_ZERO_INDEX(layer);
622
2/2
✓ Branch 0 taken 6290120078 times.
✓ Branch 1 taken 696557173 times.
6986677251 if (layer == 0)
623 696557173 return get_scr(map, screen);
624
625
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6290120078 times.
6290120078 if (map == cur_map)
626 {
627 6290120078 int index = screen*7 + layer;
628
2/2
✓ Branch 0 taken 6289976018 times.
✓ Branch 1 taken 144060 times.
6290120078 if (temporary_screens[index])
629 6289976018 return temporary_screens[index];
630
631
2/2
✓ Branch 0 taken 1860 times.
✓ Branch 1 taken 142200 times.
144060 if (screen == home_screen)
632 1860 return &special_warp_return_scrs[layer];
633 142200 }
634
635
1/2
✓ Branch 0 taken 142200 times.
✗ Branch 1 not taken.
142200 if (screenscrolling && map == scrolling_map && !FFCore.ScrollingScreensAll.empty())
636 {
637 142200 int index = screen*7 + layer;
638
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 142200 times.
142200 if (FFCore.ScrollingScreensAll[index])
639 142200 return FFCore.ScrollingScreensAll[index];
640 }
641
642 NOTREACHED();
643 6986677251 }
644
645 // Note: layer=0 returns the base screen, layer=1 returns the first layer.
646 6564627707 mapscr* get_scr_layer(int screen, int layer)
647 {
648 6564627707 return get_scr_layer(cur_map, screen, layer);
649 }
650
651 // Note: layer=0 returns the base screen, layer=1 returns the first layer.
652 // Return nullptr if screen is not valid.
653 419069187 mapscr* get_scr_layer_valid(int screen, int layer)
654 {
655
2/2
✓ Branch 0 taken 98840427 times.
✓ Branch 1 taken 320228760 times.
419069187 if (mapscr* scr = get_scr_layer(cur_map, screen, layer); scr->is_valid())
656 98840427 return scr;
657 320228760 return nullptr;
658 419069187 }
659
660 401 mapscr* get_scr_current_region_dir(int screen, direction dir)
661 {
662 401 int x = get_region_relative_dx(screen);
663 401 int y = get_region_relative_dy(screen);
664
3/4
✓ Branch 0 taken 71 times.
✓ Branch 1 taken 330 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 71 times.
401 if (dir == left && x == 0)
665 71 return nullptr;
666
3/4
✓ Branch 0 taken 92 times.
✓ Branch 1 taken 238 times.
✓ Branch 2 taken 92 times.
✗ Branch 3 not taken.
330 if (dir == right && x == 15)
667 return nullptr;
668
3/4
✓ Branch 0 taken 49 times.
✓ Branch 1 taken 281 times.
✓ Branch 2 taken 49 times.
✗ Branch 3 not taken.
330 if (dir == down && y == 7)
669 return nullptr;
670
3/4
✓ Branch 0 taken 189 times.
✓ Branch 1 taken 141 times.
✓ Branch 2 taken 189 times.
✗ Branch 3 not taken.
330 if (dir == up && y == 0)
671 189 return nullptr;
672
673 141 screen = screen_index_direction(screen, dir);
674
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 141 times.
141 if (is_in_current_region(screen))
675 return get_scr(screen);
676
677 141 return nullptr;
678 401 }
679
680 183838 ffc_handle_t get_ffc_handle(ffc_id_t id)
681 {
682 183838 uint8_t screen = get_screen_for_region_index_offset(id / MAXFFCS);
683 183838 uint8_t i = id % MAXFFCS;
684 183838 mapscr* scr = get_scr(screen);
685 183838 ffcdata* ffc = &scr->getFFC(id % MAXFFCS);
686 183838 return {scr, screen, id, i, ffc};
687 }
688
689 34571 std::pair<int32_t, int32_t> translate_screen_coordinates_to_world(int screen, int x, int y)
690 {
691 34571 x += get_region_relative_dx(screen) * 256;
692 34571 y += get_region_relative_dy(screen) * 176;
693 34571 return {x, y};
694 }
695
696 1056043 std::pair<int32_t, int32_t> translate_screen_coordinates_to_world(int screen)
697 {
698 1056043 int x = get_region_relative_dx(screen) * 256;
699 1056043 int y = get_region_relative_dy(screen) * 176;
700 1056043 return {x, y};
701 }
702
703 12689421665 int32_t COMBOPOS(int32_t x, int32_t y)
704 {
705 DCHECK(x >= 0 && x < 256 && y >= 0 && y < 176);
706 12689421665 return (y & 0xF0) + (x >> 4);
707 }
708 int32_t COMBOPOS_B(int32_t x, int32_t y)
709 {
710 if(unsigned(x) >= 256 || unsigned(y) >= 176)
711 return -1;
712 return (y & 0xF0) + (x >> 4);
713 }
714 3953286650 int32_t COMBOX(int32_t pos)
715 {
716 3953286650 return pos % 16 * 16;
717 }
718 3953286650 int32_t COMBOY(int32_t pos)
719 {
720 3953286650 return pos & 0xF0;
721 }
722
723 116966139 rpos_t COMBOPOS_REGION(int32_t x, int32_t y)
724 {
725
2/2
✓ Branch 0 taken 89808187 times.
✓ Branch 1 taken 27157952 times.
116966139 if (!is_in_scrolling_region())
726 89808187 return (rpos_t) COMBOPOS(x, y);
727
728 DCHECK(is_in_world_bounds(x, y));
729 27157952 int scr_dx = x / (16*16);
730 27157952 int scr_dy = y / (11*16);
731 27157952 int pos = COMBOPOS(x%256, y%176);
732 27157952 return static_cast<rpos_t>((scr_dx + scr_dy * cur_region.screen_width)*176 + pos);
733 116966139 }
734 6958797899 rpos_t COMBOPOS_REGION_B(int32_t x, int32_t y)
735 {
736
2/2
✓ Branch 0 taken 1553141 times.
✓ Branch 1 taken 6957244758 times.
6958797899 if (!is_in_world_bounds(x, y))
737 1553141 return rpos_t::None;
738
739 6957244758 int scr_dx = x / (16*16);
740 6957244758 int scr_dy = y / (11*16);
741 6957244758 int pos = COMBOPOS(x%256, y%176);
742 6957244758 return static_cast<rpos_t>((scr_dx + scr_dy * cur_region.screen_width)*176 + pos);
743 6958797899 }
744 28725890 std::pair<int32_t, int32_t> COMBOXY_REGION(rpos_t rpos)
745 {
746 28725890 int scr_index = static_cast<int32_t>(rpos) / 176;
747 28725890 int scr_dx = scr_index % cur_region.screen_width;
748 28725890 int scr_dy = scr_index / cur_region.screen_width;
749 28725890 int pos = RPOS_TO_POS(rpos);
750 28725890 int x = scr_dx*16*16 + COMBOX(pos);
751 28725890 int y = scr_dy*11*16 + COMBOY(pos);
752 28725890 return {x, y};
753 }
754 182363 int32_t COMBOX_REGION(rpos_t rpos)
755 {
756 182363 auto [x, y] = COMBOXY_REGION(rpos);
757 182363 return x;
758 }
759 134192 int32_t COMBOY_REGION(rpos_t rpos)
760 {
761 134192 auto [x, y] = COMBOXY_REGION(rpos);
762 134192 return y;
763 }
764
765 70177 rpos_t COMBOPOS_REGION_INDEX(int32_t x, int32_t y)
766 {
767 DCHECK(is_in_world_bounds(x, y));
768
1/2
✓ Branch 0 taken 70177 times.
✗ Branch 1 not taken.
70177 if (!is_in_scrolling_region())
769 70177 return (rpos_t)(x + y * 16);
770
771 int scr_dx = x / 16;
772 int scr_dy = y / 11;
773 x %= 16;
774 y %= 11;
775 return static_cast<rpos_t>((scr_dx + scr_dy * cur_region.screen_width)*176 + x + y * 16);
776 70177 }
777 70632 std::pair<int32_t, int32_t> COMBOXY_REGION_INDEX(rpos_t rpos)
778 {
779 70632 int scr_index = static_cast<int32_t>(rpos) / 176;
780 70632 int scr_dx = scr_index % cur_region.screen_width;
781 70632 int scr_dy = scr_index / cur_region.screen_width;
782 70632 int pos = RPOS_TO_POS(rpos);
783 70632 int x = scr_dx*16 + pos%16;
784 70632 int y = scr_dy*11 + pos/16;
785 70632 return {x, y};
786 }
787
788 92311206 int32_t mapind(int32_t map, int32_t scr)
789 {
790 92311206 return map * MAPSCRSNORMAL + scr;
791 }
792
793 FONT *get_zc_font(int index);
794
795 extern sprite_list guys, items, Ewpns, Lwpns, chainlinks, decorations;
796 extern movingblock mblock2; //mblock[4]?
797 extern portal mirror_portal;
798
799 void Z_message_d(const char *format,...)
800 {
801 #ifdef _DEBUG
802 char buf[512];
803 va_list ap;
804 va_start(ap, format);
805 vsprintf(buf, format, ap);
806 va_end(ap);
807
808 al_trace("%s",buf);
809 #else
810 format=format;
811 #endif
812 }
813
814
815
816 bool checktrigger=false;
817
818 void clear_dmap(word i)
819 {
820 DMaps[i].clear();
821 }
822
823 void clear_dmaps()
824 {
825 for(int32_t i=0; i<MAXDMAPS; i++)
826 {
827 clear_dmap(i);
828 }
829 }
830
831 235190031 int32_t isdungeon(int32_t dmap, int32_t screen)
832 {
833
2/2
✓ Branch 0 taken 235142671 times.
✓ Branch 1 taken 47360 times.
235190031 if (dmap < 0) dmap = cur_dmap;
834
835 // dungeons can have any dlevel above 0
836
2/2
✓ Branch 0 taken 133940586 times.
✓ Branch 1 taken 101249445 times.
235190031 if((DMaps[dmap].type&dmfTYPE) == dmDNGN)
837 {
838
2/2
✓ Branch 0 taken 9961 times.
✓ Branch 1 taken 101239484 times.
101249445 if (get_canonical_scr(cur_map, screen)->flags6&fCAVEROOM)
839 9961 return 0;
840
841 101239484 return 1;
842 }
843
844 // dlevels that aren't dungeons are caves
845
2/2
✓ Branch 0 taken 36827 times.
✓ Branch 1 taken 133903759 times.
133940586 if (get_canonical_scr(cur_map, screen)->flags6&fDUNGEONROOM)
846 36827 return 1;
847
848 133903759 return 0;
849 235190031 }
850
851 43126147 int32_t isdungeon(int32_t screen)
852 {
853 43126147 return isdungeon(cur_dmap, screen);
854 }
855
856 191931744 int32_t isdungeon()
857 {
858 191931744 return isdungeon(cur_dmap, Hero.current_screen);
859 }
860
861 92459 bool canPermSecret(int32_t dmap, int32_t screen)
862 {
863
2/2
✓ Branch 0 taken 13910 times.
✓ Branch 1 taken 78549 times.
92459 return (!isdungeon(dmap, screen) || get_qr(qr_DUNGEON_DMAPS_PERM_SECRETS));
864 }
865
866 1263839454 int32_t MAPCOMBO(int32_t x, int32_t y)
867 {
868 1263839454 x = vbound(x, 0, world_w-1);
869 1263839454 y = vbound(y, 0, world_h-1);
870 1263839454 int pos = COMBOPOS(x%256, y%176);
871 1263839454 mapscr* scr = get_scr_for_world_xy(x, y);
872 1263839454 return scr->data[pos];
873 }
874
875 //specific layers 1 to 6
876 1488561788 int32_t MAPCOMBOL(int32_t layer,int32_t x,int32_t y)
877 {
878 DCHECK(layer >= 1 && layer <= 6);
879
3/4
✓ Branch 0 taken 1468658334 times.
✓ Branch 1 taken 19903454 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1468658334 times.
1488561788 if (!is_in_world_bounds(x, y) || layer <= 0)
880 19903454 return 0;
881
882 1468658334 mapscr* m = get_scr_for_world_xy_layer(x, y, layer);
883
2/2
✓ Branch 0 taken 472740182 times.
✓ Branch 1 taken 995918152 times.
1468658334 if (!m->is_valid())
884 995918152 return 0;
885
886 472740182 int pos = COMBOPOS(x%256, y%176);
887 472740182 return m->data[pos];
888 1488561788 }
889
890 int32_t MAPCSETL(int32_t layer,int32_t x,int32_t y)
891 {
892 DCHECK(layer >= 1 && layer <= 6);
893 if (!is_in_world_bounds(x, y) || layer <= 0)
894 return 0;
895
896 mapscr* m = get_scr_for_world_xy_layer(x, y, layer);
897 if (!m->is_valid())
898 return 0;
899
900 int pos = COMBOPOS(x%256, y%176);
901 return m->cset[pos];
902 }
903
904 372352 int32_t MAPFLAGL(int32_t layer,int32_t x,int32_t y)
905 {
906 DCHECK(layer >= 1 && layer <= 6);
907
2/4
✓ Branch 0 taken 372352 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 372352 times.
372352 if (!is_in_world_bounds(x, y) || layer <= 0)
908 return 0;
909
910 372352 mapscr* m = get_scr_for_world_xy_layer(x, y, layer);
911
2/2
✓ Branch 0 taken 345286 times.
✓ Branch 1 taken 27066 times.
372352 if (!m->is_valid())
912 27066 return 0;
913
914 345286 int pos = COMBOPOS(x%256, y%176);
915 345286 return m->sflag[pos];
916 372352 }
917
918 40979 int32_t COMBOTYPEL(int32_t layer,int32_t x,int32_t y)
919 {
920 DCHECK(layer >= 1 && layer <= 6);
921
2/4
✓ Branch 0 taken 40979 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 40979 times.
40979 if (!is_in_world_bounds(x, y) || layer <= 0)
922 return 0;
923
924 40979 mapscr* m = get_scr_for_world_xy_layer(x, y, layer);
925
2/2
✓ Branch 0 taken 40624 times.
✓ Branch 1 taken 355 times.
40979 if (!m->is_valid())
926 355 return 0;
927
928 40624 int pos = COMBOPOS(x%256, y%176);
929 40624 return combobuf[m->data[pos]].type;
930 40979 }
931
932 371064 int32_t MAPCOMBOFLAGL(int32_t layer,int32_t x,int32_t y)
933 {
934 DCHECK(layer >= 1 && layer <= 6);
935
2/4
✓ Branch 0 taken 371064 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 371064 times.
371064 if (!is_in_world_bounds(x, y) || layer <= 0)
936 return 0;
937
938 371064 mapscr* m = get_scr_for_world_xy_layer(x, y, layer);
939
2/2
✓ Branch 0 taken 343998 times.
✓ Branch 1 taken 27066 times.
371064 if (!m->is_valid())
940 27066 return 0;
941
942 343998 int pos = COMBOPOS(x%256, y%176);
943 343998 return combobuf[m->data[pos]].flag;
944 371064 }
945
946
947 // True if the FFC covers x, y and is not ethereal or a changer.
948 2675853948 bool ffcIsAt(const ffc_handle_t& ffc_handle, int32_t x, int32_t y)
949 {
950
2/2
✓ Branch 0 taken 750008244 times.
✓ Branch 1 taken 1925845704 times.
2675853948 if (ffc_handle.data()<=0)
951 750008244 return false;
952
953
2/2
✓ Branch 0 taken 314946537 times.
✓ Branch 1 taken 1610899167 times.
1925845704 if((ffc_handle.ffc->flags&(ffc_changer|ffc_ethereal))!=0)
954 314946537 return false;
955
956 1610899167 int32_t fx=ffc_handle.ffc->x.getInt();
957
4/4
✓ Branch 0 taken 1108808422 times.
✓ Branch 1 taken 502090745 times.
✓ Branch 2 taken 990417881 times.
✓ Branch 3 taken 118390541 times.
1610899167 if(x<fx || x>fx+(ffc_handle.scr->ffEffectWidth(ffc_handle.i)-1)) // FFC sizes are weird.
958 1492508626 return false;
959
960 118390541 int32_t fy=ffc_handle.ffc->y.getInt();
961
4/4
✓ Branch 0 taken 84638375 times.
✓ Branch 1 taken 33752166 times.
✓ Branch 2 taken 64688475 times.
✓ Branch 3 taken 19949900 times.
118390541 if(y<fy || y>fy+(ffc_handle.scr->ffEffectHeight(ffc_handle.i)-1))
962 98440641 return false;
963
964 19949900 return true;
965 2675853948 }
966
967 829812448 int32_t MAPFFCOMBO(int32_t x,int32_t y)
968 {
969
2/2
✓ Branch 0 taken 11864553 times.
✓ Branch 1 taken 817947895 times.
829812448 if (auto ffc_handle = getFFCAt(x, y))
970 11864553 return ffc_handle->data();
971 817947895 return 0;
972 829812448 }
973
974 207232 int32_t MAPCSET(int32_t x, int32_t y)
975 {
976
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 207232 times.
207232 if (!is_in_world_bounds(x, y))
977 return 0;
978 207232 mapscr* scr = get_scr_for_world_xy(x, y);
979 207232 int pos = COMBOPOS(x%256, y%176);
980 207232 return scr->cset[pos];
981 207232 }
982
983 87058293 int32_t MAPFLAG(int32_t x, int32_t y)
984 {
985
2/2
✓ Branch 0 taken 28507 times.
✓ Branch 1 taken 87029786 times.
87058293 if (!is_in_world_bounds(x, y))
986 28507 return 0;
987 87029786 mapscr* scr = get_scr_for_world_xy(x, y);
988 87029786 int pos = COMBOPOS(x%256, y%176);
989 87029786 return scr->sflag[pos];
990 87058293 }
991
992 95535040 int32_t COMBOTYPE(int32_t x,int32_t y)
993 {
994 95535040 int32_t b=1;
995
2/2
✓ Branch 0 taken 64699716 times.
✓ Branch 1 taken 30835324 times.
95535040 if(x&8) b<<=2;
996
2/2
✓ Branch 0 taken 60202941 times.
✓ Branch 1 taken 35332099 times.
95535040 if(y&8) b<<=1;
997
998
2/2
✓ Branch 0 taken 191062333 times.
✓ Branch 1 taken 95519803 times.
286582136 for (int32_t i = 0; i <= 1; ++i)
999 {
1000
2/2
✓ Branch 0 taken 158746666 times.
✓ Branch 1 taken 32315667 times.
191062333 if (get_qr(qr_OLD_BRIDGE_COMBOS))
1001 {
1002
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 158746666 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
158746666 if (combobuf[MAPCOMBO2(i,x,y)].type == cBRIDGE && !_walkflag_layer(x, y, i)) return cNONE;
1003 158746666 }
1004 else
1005 {
1006
4/4
✓ Branch 0 taken 18389 times.
✓ Branch 1 taken 32297278 times.
✓ Branch 2 taken 3152 times.
✓ Branch 3 taken 15237 times.
32315667 if (combobuf[MAPCOMBO2(i,x,y)].type == cBRIDGE && _effectflag_layer(x, y, i)) return cNONE;
1007 }
1008 191047096 }
1009
1010 95519803 newcombo const& cmb = combobuf[MAPCOMBO(x,y)];
1011
5/6
✓ Branch 0 taken 3536077 times.
✓ Branch 1 taken 91983726 times.
✓ Branch 2 taken 1909096 times.
✓ Branch 3 taken 1626981 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 1909096 times.
95519803 if (cmb.type == cWATER && (cmb.walk&b) && ((cmb.walk>>4)&b))
1012 {
1013
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1909096 times.
1909096 if(cmb.usrflags&cflag4) return cSHALLOWWATER;
1014
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1909096 times.
1909096 if(cmb.usrflags&cflag3) return cNONE;
1015 1909096 }
1016 95519803 return cmb.type;
1017 95535040 }
1018
1019 59029490 int32_t FFCOMBOTYPE(int32_t x,int32_t y)
1020 {
1021 59029490 return combobuf[MAPFFCOMBO(x,y)].type;
1022 }
1023
1024 7147445 int32_t FFORCOMBO(int32_t x, int32_t y)
1025 {
1026
2/2
✓ Branch 0 taken 78428 times.
✓ Branch 1 taken 7069017 times.
7147445 if (auto ffc_handle = getFFCAt(x, y))
1027 78428 return ffc_handle->data();
1028
1029 7069017 return MAPCOMBO(x,y);
1030 7147445 }
1031
1032 int32_t FFORCOMBOTYPE(int32_t x, int32_t y)
1033 {
1034 for (int32_t i = 0; i <= 1; ++i)
1035 {
1036 if (get_qr(qr_OLD_BRIDGE_COMBOS))
1037 {
1038 if (combobuf[MAPCOMBO2(i,x,y)].type == cBRIDGE && !_walkflag_layer(x,y,i)) return cNONE;
1039 }
1040 else
1041 {
1042 if (combobuf[MAPCOMBO2(i,x,y)].type == cBRIDGE && _effectflag_layer(x,y,i)) return cNONE;
1043 }
1044 }
1045 int32_t b=1;
1046
1047 if(x&8) b<<=2;
1048
1049 if(y&8) b<<=1;
1050 newcombo const& cmb = combobuf[FFORCOMBO(x,y)];
1051 if (cmb.type == cWATER && (cmb.usrflags&cflag4) && (cmb.walk&b)) return cSHALLOWWATER;
1052 if (cmb.type == cWATER && (cmb.usrflags&cflag3) && (cmb.walk&b)) return cNONE;
1053 return cmb.type;
1054 }
1055
1056 int32_t FFORCOMBO_L(int32_t layer, int32_t x, int32_t y)
1057 {
1058 if (auto ffc_handle = getFFCAt(x, y))
1059 return ffc_handle->data();
1060
1061 return layer ? MAPCOMBOL(layer, x, y) : MAPCOMBO(x,y);
1062 }
1063
1064 int32_t FFORCOMBOTYPE_L(int32_t layer, int32_t x, int32_t y)
1065 {
1066 return combobuf[FFORCOMBO_L(layer,x,y)].type;
1067 }
1068
1069 83411087 int32_t MAPCOMBOFLAG(int32_t x,int32_t y)
1070 {
1071
2/2
✓ Branch 0 taken 28219 times.
✓ Branch 1 taken 83382868 times.
83411087 if (!is_in_world_bounds(x, y))
1072 28219 return 0;
1073
1074 83382868 mapscr* scr = get_scr_for_world_xy(x, y);
1075 83382868 int pos = COMBOPOS(x%256, y%176);
1076 83382868 return combobuf[scr->data[pos]].flag;
1077 83411087 }
1078
1079 68111964 int32_t MAPFFCOMBOFLAG(int32_t x,int32_t y)
1080 {
1081
2/2
✓ Branch 0 taken 777663 times.
✓ Branch 1 taken 67334301 times.
68111964 if (auto ffc_handle = getFFCAt(x, y))
1082 777663 return ffc_handle->cflag();
1083
1084 67334301 return 0;
1085 68111964 }
1086
1087 1237722972 std::optional<ffc_handle_t> getFFCAt(int32_t x, int32_t y)
1088 {
1089 2784688763 return find_ffc([&](const ffc_handle_t& ffc_handle) {
1090 1546965791 return ffcIsAt(ffc_handle, x, y);
1091 });
1092 }
1093
1094 3051 int32_t MAPCOMBO(const rpos_handle_t& rpos_handle)
1095 {
1096
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3051 times.
3051 if (!rpos_handle.scr->is_valid()) return 0;
1097 3051 return rpos_handle.data();
1098 3051 }
1099
1100 3017757367 int32_t MAPCOMBO2(int32_t layer, int32_t x, int32_t y)
1101 {
1102 DCHECK_LAYER_NEG1_INDEX(layer);
1103
2/2
✓ Branch 0 taken 22065451 times.
✓ Branch 1 taken 2995691916 times.
3017757367 if (!is_in_world_bounds(x, y)) return 0;
1104
2/2
✓ Branch 0 taken 2896540143 times.
✓ Branch 1 taken 99151773 times.
2995691916 if (layer == -1) return MAPCOMBO(x, y);
1105
1106 2896540143 auto rpos_handle = get_rpos_handle_for_world_xy(x, y, layer + 1);
1107
2/2
✓ Branch 0 taken 1796113957 times.
✓ Branch 1 taken 1100426186 times.
2896540143 if (!rpos_handle.scr->is_valid()) return 0;
1108
1109 1100426186 return rpos_handle.data();
1110 3017757367 }
1111
1112 19160886 static void _handle_screen_load_trigger(const combined_handle_t& handle)
1113 {
1114 19160886 auto cid = handle.data();
1115 19160886 auto* cmb = &handle.combo();
1116 19160886 bool done = false;
1117 19160886 std::set<int32_t> visited;
1118
2/2
✓ Branch 0 taken 19160886 times.
✓ Branch 1 taken 19160886 times.
38321772 while(!done)
1119 {
1120
2/4
✓ Branch 0 taken 19160886 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 19160886 times.
19160886 if(visited.contains(cid))
1121 {
1122 Z_error("Combo '%d' was part of an infinite trigger loop, breaking out of loop", cid);
1123 break; // prevent infinite loop
1124 }
1125
1/2
✓ Branch 0 taken 19160886 times.
✗ Branch 1 not taken.
19160886 visited.insert(cid);
1126
1127 19160886 done = true; // don't loop again unless something changes
1128
1/2
✓ Branch 0 taken 19160886 times.
✗ Branch 1 not taken.
20045029 trig_each_combo_trigger(handle, [&](combo_trigger const& trig){
1129 884143 return trig.trigger_flags.get(TRIGFLAG_SCREENLOAD);
1130 });
1131
2/4
✓ Branch 0 taken 19160886 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 19160886 times.
19160886 if(handle.data() != cid)
1132 {
1133 cid = handle.data();
1134 cmb = &handle.combo();
1135 done = false; // loop again for the new combo
1136 }
1137 }
1138 19160886 }
1139 52906 static void handle_screen_load_trigger(const screen_handles_t& screen_handles)
1140 {
1141 52906 for_every_combo_in_screen(screen_handles, _handle_screen_load_trigger);
1142 52906 }
1143 36496 void handle_region_load_trigger()
1144 {
1145
2/2
✓ Branch 0 taken 152 times.
✓ Branch 1 taken 36344 times.
36496 if (is_in_scrolling_region())
1146 {
1147
2/2
✓ Branch 0 taken 152 times.
✓ Branch 1 taken 19456 times.
19608 for (int screen = 0; screen < 128; screen++)
1148 {
1149
2/2
✓ Branch 0 taken 18156 times.
✓ Branch 1 taken 1300 times.
19456 if (is_in_current_region(screen))
1150 1300 handle_screen_load_trigger(create_screen_handles_one(get_scr(screen)));
1151 19456 }
1152 152 }
1153 36344 else handle_screen_load_trigger(create_screen_handles_one(get_scr(Hero.current_screen)));
1154 36496 }
1155
1156 15262 static void apply_state_changes_to_screen(mapscr& scr, int32_t map, int32_t screen, int32_t flags, bool secrets_do_replay_comment)
1157 {
1158 15262 auto screen_handles = create_screen_handles_one(&scr);
1159
1160
3/4
✓ Branch 0 taken 539 times.
✓ Branch 1 taken 14723 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 539 times.
15262 if ((flags & mSECRET) && canPermSecret(cur_dmap, screen))
1161 {
1162 539 reveal_hidden_stairs(&scr, screen, false);
1163 539 bool do_layers = false;
1164 539 bool from_active_screen = false;
1165 539 trigger_secrets_for_screen_internal(screen_handles, do_layers, from_active_screen, -3, secrets_do_replay_comment);
1166 539 }
1167
1/2
✓ Branch 0 taken 15262 times.
✗ Branch 1 not taken.
15262 if (flags & mLIGHTBEAM)
1168 {
1169 for_every_rpos_in_screen(screen_handles, [&](const rpos_handle_t& rpos_handle) {
1170 if (rpos_handle.ctype() == cLIGHTTARGET)
1171 {
1172 if (!(rpos_handle.combo().usrflags&cflag1)) //Unlit version
1173 rpos_handle.increment_data();
1174 }
1175 });
1176 }
1177
1178 15262 int lvl = DMaps[cur_dmap].level;
1179 15262 toggle_switches(game->lvlswitches[lvl], true, screen_handles);
1180 15262 toggle_gswitches_load(screen_handles);
1181
1182
2/2
✓ Branch 0 taken 15170 times.
✓ Branch 1 taken 92 times.
15262 if(flags&mLOCKBLOCK) // if special stuff done before
1183 {
1184 92 remove_screenstatecombos2(screen_handles, false, cLOCKBLOCK, cLOCKBLOCK2);
1185 92 }
1186
1187
1/2
✓ Branch 0 taken 15262 times.
✗ Branch 1 not taken.
15262 if(flags&mBOSSLOCKBLOCK) // if special stuff done before
1188 {
1189 remove_screenstatecombos2(screen_handles, false, cBOSSLOCKBLOCK, cBOSSLOCKBLOCK2);
1190 }
1191
1192
1/2
✓ Branch 0 taken 15262 times.
✗ Branch 1 not taken.
15262 if(flags&mCHEST) // if special stuff done before
1193 {
1194 remove_screenstatecombos2(screen_handles, false, cCHEST, cCHEST2);
1195 }
1196
1197
1/2
✓ Branch 0 taken 15262 times.
✗ Branch 1 not taken.
15262 if(flags&mCHEST) // if special stuff done before
1198 {
1199 remove_screenstatecombos2(screen_handles, false, cLOCKEDCHEST, cLOCKEDCHEST2);
1200 }
1201
1202
1/2
✓ Branch 0 taken 15262 times.
✗ Branch 1 not taken.
15262 if(flags&mBOSSCHEST) // if special stuff done before
1203 {
1204 remove_screenstatecombos2(screen_handles, false, cBOSSCHEST, cBOSSCHEST2);
1205 }
1206
1207
1208 15262 int mi = mapind(map, screen);
1209 15262 clear_xdoors_mi(screen_handles, mi);
1210 15262 clear_xstatecombos_mi(screen_handles, mi);
1211
1212 15262 handle_screen_load_trigger(screen_handles);
1213 15262 }
1214
1215 40981 std::optional<mapscr> load_temp_mapscr_and_apply_secrets(int32_t map, int32_t screen, int32_t layer, bool secrets, bool secrets_do_replay_comment)
1216 {
1217
2/4
✓ Branch 0 taken 40981 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 40981 times.
40981 if (map < 0 || screen < 0)
1218 return std::nullopt;
1219
1220 40981 const mapscr* source = get_canonical_scr(map, screen);
1221
2/2
✓ Branch 0 taken 39256 times.
✓ Branch 1 taken 1725 times.
40981 if (!source->is_valid())
1222 1725 return std::nullopt;
1223
1224
2/2
✓ Branch 0 taken 7936 times.
✓ Branch 1 taken 31320 times.
39256 if (layer >= 0)
1225 {
1226
2/2
✓ Branch 0 taken 23994 times.
✓ Branch 1 taken 7326 times.
31320 if (source->layermap[layer] <= 0)
1227 23994 return std::nullopt;
1228
1229 7326 source = get_canonical_scr(source->layermap[layer] - 1, source->layerscreen[layer]);
1230
1/2
✓ Branch 0 taken 7326 times.
✗ Branch 1 not taken.
7326 if (!source->is_valid())
1231 return std::nullopt;
1232 7326 }
1233
1234
1/2
✓ Branch 0 taken 15262 times.
✗ Branch 1 not taken.
15262 int flags = secrets ? game->maps[mapind(map, screen)] : 0;
1235 15262 mapscr scr = *source;
1236
1/2
✓ Branch 0 taken 15262 times.
✗ Branch 1 not taken.
15262 apply_state_changes_to_screen(scr, map, screen, flags, secrets_do_replay_comment);
1237
1238
1/2
✓ Branch 0 taken 15262 times.
✗ Branch 1 not taken.
15262 return scr;
1239 40981 }
1240
1241 14990 static int32_t MAPCOMBO3_impl(int32_t map, int32_t screen, int32_t layer, int32_t pos, bool secrets)
1242 {
1243
2/4
✓ Branch 0 taken 14990 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 14990 times.
14990 if (map < 0 || screen < 0) return 0;
1244
1245
2/4
✓ Branch 0 taken 14990 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 14990 times.
14990 if(pos>175 || pos < 0)
1246 return 0;
1247
1248 // TODO: consider caching this (invalidate on any modification via scripting, or anything
1249 // `apply_state_changes_to_screen` checks).
1250
4/5
✓ Branch 0 taken 4736 times.
✓ Branch 1 taken 10254 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 4736 times.
✓ Branch 4 taken 10254 times.
19726 if (auto s = load_temp_mapscr_and_apply_secrets(map, screen, layer, secrets))
1251 4736 return s->data[pos];
1252
1253 10254 return 0;
1254 14990 }
1255
1256 // Read from the current temporary screens or, if (map, screen) is not loaded,
1257 // load that screen and apply the relevant secrets before evaluating the combo at that position.
1258 251302544 int32_t MAPCOMBO3(int32_t map, int32_t screen, int32_t layer, int32_t x, int32_t y, bool secrets)
1259 {
1260 DCHECK_LAYER_NEG1_INDEX(layer);
1261 DCHECK(map >= 0 && screen >= 0);
1262
1263
2/2
✓ Branch 0 taken 251287554 times.
✓ Branch 1 taken 14990 times.
251302544 if (is_in_current_region(map, screen)) return MAPCOMBO2(layer, x, y);
1264
1265 // Screen is not in the current region, so we have to load and trigger some secrets.
1266 14990 int pos = COMBOPOS(x, y);
1267 14990 return MAPCOMBO3_impl(map, screen, layer, pos, secrets);
1268 251302544 }
1269
1270 int32_t MAPCOMBO3(int32_t map, int32_t screen, int32_t layer, rpos_t rpos, bool secrets)
1271 {
1272 DCHECK_LAYER_NEG1_INDEX(layer);
1273 DCHECK(map >= 0 && screen >= 0);
1274 DCHECK(is_valid_rpos(rpos));
1275
1276 if (is_in_current_region(map, screen)) return MAPCOMBO(get_rpos_handle(rpos, layer + 1));
1277
1278 // Screen is not currently loaded, so we have to load and trigger some secrets.
1279 return MAPCOMBO3_impl(map, screen, layer, RPOS_TO_POS(rpos), secrets);
1280 }
1281
1282 int32_t MAPCSET2(int32_t layer,int32_t x,int32_t y)
1283 {
1284 DCHECK_LAYER_NEG1_INDEX(layer);
1285 if (!is_in_world_bounds(x, y))
1286 return 0;
1287 if (layer == -1) return MAPCSET(x, y);
1288
1289 auto rpos_handle = get_rpos_handle_for_world_xy(x, y, layer + 1);
1290 if (!rpos_handle.scr->is_valid()) return 0;
1291
1292 return rpos_handle.cset();
1293 }
1294
1295 102412209 int32_t MAPFLAG2(int32_t layer,int32_t x,int32_t y)
1296 {
1297 DCHECK_LAYER_NEG1_INDEX(layer);
1298
3/4
✓ Branch 0 taken 5385623 times.
✓ Branch 1 taken 97026586 times.
✓ Branch 2 taken 5385623 times.
✗ Branch 3 not taken.
102412209 if (!get_qr(qr_BUGGED_LAYERED_FLAGS) && (!is_in_world_bounds(x, y)))
1299 return 0;
1300
2/2
✓ Branch 0 taken 84274547 times.
✓ Branch 1 taken 18137662 times.
102412209 if (layer == -1) return MAPFLAG(x, y);
1301
1302 84274547 auto rpos_handle = get_rpos_handle_for_world_xy(x, y, layer + 1);
1303
2/2
✓ Branch 0 taken 63730019 times.
✓ Branch 1 taken 20544528 times.
84274547 if (!rpos_handle.scr->is_valid()) return 0;
1304
1305 20544528 return rpos_handle.sflag();
1306 102412209 }
1307
1308 int32_t COMBOTYPE2(int32_t layer,int32_t x,int32_t y)
1309 {
1310 if(layer < 1)
1311 {
1312 for (int32_t i = layer+1; i <= 1; ++i)
1313 {
1314 if (get_qr(qr_OLD_BRIDGE_COMBOS))
1315 {
1316 if (combobuf[MAPCOMBO2(i,x,y)].type == cBRIDGE && !_walkflag_layer(x,y,i)) return cNONE;
1317 }
1318 else
1319 {
1320 if (combobuf[MAPCOMBO2(i,x,y)].type == cBRIDGE && _effectflag_layer(x,y,i)) return cNONE;
1321 }
1322 }
1323 }
1324 if(layer==-1) return COMBOTYPE(x,y);
1325
1326 auto rpos_handle = get_rpos_handle_for_world_xy(x, y, layer + 1);
1327 if (!rpos_handle.scr->is_valid()) return 0;
1328
1329 return rpos_handle.ctype();
1330 }
1331
1332 // Returns the flag for the combo at the given position.
1333 // This is also known as an "inherent flag".
1334 100578885 int32_t MAPCOMBOFLAG2(int32_t layer,int32_t x,int32_t y)
1335 {
1336 DCHECK_LAYER_NEG1_INDEX(layer);
1337
2/2
✓ Branch 0 taken 288 times.
✓ Branch 1 taken 100578597 times.
100578885 if (!is_in_world_bounds(x, y))
1338 288 return 0;
1339
2/2
✓ Branch 0 taken 84177975 times.
✓ Branch 1 taken 16400622 times.
100578597 if (layer == -1) return MAPCOMBOFLAG(x, y);
1340
1341 84177975 auto rpos_handle = get_rpos_handle_for_world_xy(x, y, layer + 1);
1342
2/2
✓ Branch 0 taken 63748345 times.
✓ Branch 1 taken 20429630 times.
84177975 if (!rpos_handle.scr->is_valid()) return 0;
1343
1344 20429630 return rpos_handle.cflag();
1345 100578885 }
1346
1347 11709519 bool HASFLAG(int32_t flag, int32_t layer, rpos_t rpos)
1348 {
1349 DCHECK_LAYER_ZERO_INDEX(layer);
1350 11709519 auto rpos_handle = get_rpos_handle(rpos, layer);
1351
2/2
✓ Branch 0 taken 4485430 times.
✓ Branch 1 taken 7224089 times.
11709519 if (!rpos_handle.scr->is_valid()) return false;
1352
2/2
✓ Branch 0 taken 4565 times.
✓ Branch 1 taken 7219524 times.
7224089 if (rpos_handle.sflag() == flag) return true;
1353
2/2
✓ Branch 0 taken 37705 times.
✓ Branch 1 taken 7181819 times.
7219524 if (rpos_handle.cflag() == flag) return true;
1354 7181819 return false;
1355 11709519 }
1356
1357 1708873 bool HASFLAG_ANY(int32_t flag, rpos_t rpos)
1358 {
1359 DCHECK(is_valid_rpos(rpos));
1360
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1708873 times.
1708873 if (rpos > region_max_rpos) return false;
1361
1362
2/2
✓ Branch 0 taken 11709519 times.
✓ Branch 1 taken 1666603 times.
13376122 for(auto q = 0; q < 7; ++q)
1363 {
1364
2/2
✓ Branch 0 taken 42270 times.
✓ Branch 1 taken 11667249 times.
11709519 if(HASFLAG(flag, q, rpos))
1365 42270 return true;
1366 11667249 }
1367 1666603 return false;
1368 1708873 }
1369
1370 const char *screenstate_string[32] =
1371 {
1372 "Door Up", "Door Down", "Door Left", "Door Right", "Item", "Special Item", "Some Enemies Never Return",
1373 "Temporary No Return", "Lock Blocks", "Boss Lock Blocks", "Chests", "Locked Chests",
1374 "Boss Locked Chests", "Secrets", "Visited", "Light Beams",
1375 "All Enemies Don't Return", "<Unused>", "<Unused>", "<Unused>", "<Unused>", "<Unused>", "<Unused>", "<Unused>",
1376 "<Unused>", "<Unused>", "<Unused>", "<Unused>", "<Unused>", "<Unused>", "<Unused>", "<Unused>",
1377 };
1378
1379 36562 void eventlog_mapflags()
1380 {
1381 36562 std::ostringstream oss;
1382
1383 36562 int mi = mapind(cur_map, home_screen);
1384
1/2
✓ Branch 0 taken 36562 times.
✗ Branch 1 not taken.
36562 dword g = game->maps[mi];
1385
1386
2/4
✓ Branch 0 taken 36562 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 36562 times.
✗ Branch 3 not taken.
36562 oss << fmt::format("Screen ({}, {:02X})", cur_map+1, home_screen);
1387
2/2
✓ Branch 0 taken 15710 times.
✓ Branch 1 taken 20852 times.
36562 if(g) // Main States
1388 {
1389 static const int order[] =
1390 {
1391 mSECRET, mITEM, mSPECIALITEM, mLOCKBLOCK, mBOSSLOCKBLOCK,
1392 mCHEST, mLOCKEDCHEST, mBOSSCHEST,
1393 mDOOR_UP, mDOOR_DOWN, mDOOR_LEFT, mDOOR_RIGHT,
1394 mNEVERRET, mTMPNORET, mLIGHTBEAM, mNO_ENEMIES_RETURN
1395 };
1396
1397
1/2
✓ Branch 0 taken 15710 times.
✗ Branch 1 not taken.
15710 oss << " [";
1398 15710 bool comma = false;
1399
2/2
✓ Branch 0 taken 15710 times.
✓ Branch 1 taken 251360 times.
267070 for(int fl : order)
1400 {
1401
2/2
✓ Branch 0 taken 9640 times.
✓ Branch 1 taken 241720 times.
251360 if(!(g&fl))
1402 241720 continue;
1403 9640 byte ind = byte(log2(double(fl)));
1404
2/2
✓ Branch 0 taken 2072 times.
✓ Branch 1 taken 7568 times.
9640 if(comma)
1405
1/2
✓ Branch 0 taken 2072 times.
✗ Branch 1 not taken.
2072 oss << ", ";
1406
1/2
✓ Branch 0 taken 9640 times.
✗ Branch 1 not taken.
9640 oss << screenstate_string[ind];
1407 9640 comma = true;
1408 }
1409
1/2
✓ Branch 0 taken 15710 times.
✗ Branch 1 not taken.
15710 oss << "]";
1410 15710 }
1411
3/4
✓ Branch 0 taken 36562 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 56 times.
✓ Branch 3 taken 36506 times.
36562 if(game->xstates[mi]) // ExStates
1412 {
1413
1/2
✓ Branch 0 taken 56 times.
✗ Branch 1 not taken.
56 oss << " Ex[";
1414 56 bool comma = false;
1415
2/2
✓ Branch 0 taken 56 times.
✓ Branch 1 taken 1792 times.
1848 for(byte fl = 0; fl < 32; ++fl)
1416 {
1417
3/4
✓ Branch 0 taken 1792 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 77 times.
✓ Branch 3 taken 1715 times.
1792 if(game->xstates[mi] & (1<<fl))
1418 {
1419
2/2
✓ Branch 0 taken 21 times.
✓ Branch 1 taken 56 times.
77 if(comma)
1420
1/2
✓ Branch 0 taken 21 times.
✗ Branch 1 not taken.
21 oss << ", ";
1421
1/2
✓ Branch 0 taken 77 times.
✗ Branch 1 not taken.
77 oss << int(fl);
1422 77 comma = true;
1423 77 }
1424 1792 }
1425
1/2
✓ Branch 0 taken 56 times.
✗ Branch 1 not taken.
56 oss << "]";
1426 56 }
1427 { // ExDoors
1428
2/2
✓ Branch 0 taken 36562 times.
✓ Branch 1 taken 146248 times.
182810 for(int q = 0; q < 4; ++q)
1429 {
1430 146248 bool comma = false;
1431
3/4
✓ Branch 0 taken 146248 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 146246 times.
✓ Branch 3 taken 2 times.
146248 if(auto v = game->xdoors[mi][q])
1432 {
1433
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if(comma)
1434 oss << ",";
1435
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 else oss << " ExDoor";
1436
2/4
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
2 oss << "[" << dirstr[q];
1437
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 16 times.
18 for(int fl = 0; fl < 8; ++fl)
1438
2/2
✓ Branch 0 taken 13 times.
✓ Branch 1 taken 3 times.
19 if(v & (1<<fl))
1439
2/4
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
✗ Branch 3 not taken.
3 oss << " " << int(fl);
1440
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 oss << "]";
1441 2 comma = true;
1442 2 }
1443 146248 }
1444 }
1445
2/4
✓ Branch 0 taken 36562 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 36562 times.
36562 Z_eventlog("%s\n", oss.str().c_str());
1446 36562 }
1447
1448 // set specific flag
1449 5932 void setmapflag(mapscr* scr, uint32_t flag)
1450 {
1451
2/2
✓ Branch 0 taken 5919 times.
✓ Branch 1 taken 13 times.
5932 if (scr->screen >= 0x80) scr = special_warp_return_scr;
1452 5932 int mi = mapind(cur_map, scr->screen);
1453 5932 setmapflag_mi(scr, mi, flag);
1454 5932 }
1455 57 void setmapflag_homescr(uint32_t flag)
1456 {
1457 57 int mi = mapind(cur_map, home_screen);
1458 57 setmapflag_mi(origin_scr, mi, flag);
1459 57 }
1460 2065 void setmapflag_mi(int32_t mi, uint32_t flag)
1461 {
1462 2065 byte cscr = mi&((1<<7)-1);
1463 2065 byte cmap = (mi>>7);
1464 2065 mapscr* scr = origin_scr;
1465
2/2
✓ Branch 0 taken 835 times.
✓ Branch 1 taken 1230 times.
2065 if (is_in_current_region(cmap, cscr))
1466 1230 scr = get_scr(cmap, cscr);
1467
1468 2065 setmapflag_mi(scr, mi, flag);
1469 2065 }
1470
1471 8877 static void log_state_change(int map, int screen, std::string action)
1472 {
1473
6/6
✓ Branch 0 taken 1937 times.
✓ Branch 1 taken 6940 times.
✓ Branch 2 taken 996 times.
✓ Branch 3 taken 941 times.
✓ Branch 4 taken 352 times.
✓ Branch 5 taken 644 times.
8877 if (is_in_current_region(map, screen) || (map == cur_map && screen == home_screen))
1474 7292 Z_eventlog("[Map %d, Screen %02X (current)] %s\n", map + 1, screen, action.c_str());
1475 else
1476 1585 Z_eventlog("[Map %d, Screen %02X] %s\n", map + 1, screen, action.c_str());
1477 8877 }
1478
1479 8054 void setmapflag_mi(mapscr* scr, int32_t mi, uint32_t flag)
1480 {
1481 8054 byte cscr = mi&((1<<7)-1);
1482 8054 byte cmap = (mi>>7);
1483
1484 8054 double temp=log2((double)flag);
1485
1/2
✓ Branch 0 taken 8054 times.
✗ Branch 1 not taken.
8054 const char* state_string = flag>0 ? screenstate_string[(int32_t)temp] : "<Unknown>";
1486 8054 const char* replay_state_string = state_string;
1487
2/2
✓ Branch 0 taken 7534 times.
✓ Branch 1 taken 520 times.
8054 if(temp == 6) replay_state_string = "No Return";
1488
1489
3/4
✓ Branch 0 taken 8054 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1596 times.
✓ Branch 3 taken 6458 times.
8054 if (replay_is_active() && !(game->maps[mi] & flag))
1490
1/2
✓ Branch 0 taken 6458 times.
✗ Branch 1 not taken.
6458 replay_step_comment(fmt::format("map {} scr {} flag {}", cmap, cscr, replay_state_string));
1491 8054 game->maps[mi] |= flag;
1492
1/2
✓ Branch 0 taken 8054 times.
✗ Branch 1 not taken.
8054 log_state_change(cmap, cscr, fmt::format("State set: {}", state_string));
1493
1494
2/2
✓ Branch 0 taken 2518 times.
✓ Branch 1 taken 5536 times.
8054 if((scr->nocarry&flag)!=flag)
1495 {
1496 5536 byte nmap=TheMaps[((cmap)*MAPSCRS)+cscr].nextmap;
1497 5536 byte nscr=TheMaps[((cmap)*MAPSCRS)+cscr].nextscr;
1498
1499 5536 std::vector<int32_t> done;
1500
2/2
✓ Branch 0 taken 5423 times.
✓ Branch 1 taken 113 times.
5536 bool looped = (nmap==cmap+1 && nscr==cscr);
1501
1502
6/6
✓ Branch 0 taken 458 times.
✓ Branch 1 taken 5485 times.
✓ Branch 2 taken 51 times.
✓ Branch 3 taken 407 times.
✓ Branch 4 taken 407 times.
✓ Branch 5 taken 5536 times.
5943 while((nmap!=0) && !looped && !(nscr>=128))
1503 {
1504
3/4
✓ Branch 0 taken 407 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 191 times.
✓ Branch 3 taken 216 times.
407 if(!(game->maps[((nmap-1)<<7)+nscr] & flag))
1505 {
1506
2/4
✓ Branch 0 taken 216 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 216 times.
✗ Branch 3 not taken.
216 log_state_change(nmap, nscr, "State change carried over");
1507
2/4
✓ Branch 0 taken 216 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 216 times.
✗ Branch 3 not taken.
216 if (replay_is_active())
1508
2/4
✓ Branch 0 taken 216 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 216 times.
✗ Branch 3 not taken.
216 replay_step_comment(fmt::format("map {} scr {} flag {} carry", nmap, nscr, replay_state_string));
1509
1/2
✓ Branch 0 taken 216 times.
✗ Branch 1 not taken.
216 game->maps[((nmap-1)<<7)+nscr] |= flag;
1510 216 }
1511
1512 407 cmap=nmap;
1513 407 cscr=nscr;
1514 407 nmap=TheMaps[((cmap-1)*MAPSCRS)+cscr].nextmap;
1515 407 nscr=TheMaps[((cmap-1)*MAPSCRS)+cscr].nextscr;
1516
1517
2/2
✓ Branch 0 taken 916 times.
✓ Branch 1 taken 407 times.
1323 for(auto it = done.begin(); it != done.end(); it++)
1518 {
1519
2/2
✓ Branch 0 taken 865 times.
✓ Branch 1 taken 51 times.
916 if(*it == ((nmap-1)<<7)+nscr)
1520 51 looped = true;
1521 916 }
1522
1523
1/2
✓ Branch 0 taken 407 times.
✗ Branch 1 not taken.
407 done.push_back(((nmap-1)<<7)+nscr);
1524 }
1525 5536 }
1526 8054 }
1527
1528 void unsetmapflag_home(uint32_t flag, bool anyflag)
1529 {
1530 int mi = mapind(cur_map, home_screen);
1531 unsetmapflag_mi(origin_scr, mi, flag, anyflag);
1532 }
1533
1534 void unsetmapflag(mapscr* scr, uint32_t flag, bool anyflag)
1535 {
1536 if (scr->screen >= 0x80) scr = special_warp_return_scr;
1537 int mi = mapind(cur_map, scr->screen);
1538 unsetmapflag_mi(scr, mi, flag, anyflag);
1539 }
1540
1541 471 void unsetmapflag_mi(int32_t mi, uint32_t flag, bool anyflag)
1542 {
1543 471 byte cscr = mi&((1<<7)-1);
1544 471 byte cmap = (mi>>7);
1545 471 mapscr* scr = origin_scr;
1546
2/2
✓ Branch 0 taken 460 times.
✓ Branch 1 taken 11 times.
471 if (is_in_current_region(cmap, cscr))
1547 11 scr = get_scr(cmap, cscr);
1548
1549 471 unsetmapflag_mi(scr, mi, flag, anyflag);
1550 471 }
1551
1552 471 void unsetmapflag_mi(mapscr* scr, int32_t mi, uint32_t flag, bool anyflag)
1553 {
1554 471 byte cscr = mi&((1<<7)-1);
1555 471 byte cmap = (mi>>7);
1556
1557
2/2
✓ Branch 0 taken 460 times.
✓ Branch 1 taken 11 times.
471 if(anyflag)
1558 460 game->maps[mi] &= ~flag;
1559
2/4
✓ Branch 0 taken 11 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 11 times.
11 else if(flag==mITEM || flag==mSPECIALITEM)
1560 {
1561 if(!(scr->flags4&fNOITEMRESET))
1562 game->maps[mi] &= ~flag;
1563 }
1564 11 else game->maps[mi] &= ~flag;
1565
1566 471 double temp=log2((double)flag);
1567
1/2
✓ Branch 0 taken 471 times.
✗ Branch 1 not taken.
471 const char* state_string = flag>0 ? screenstate_string[(int32_t)temp] : "<Unknown>";
1568
1/2
✓ Branch 0 taken 471 times.
✗ Branch 1 not taken.
471 log_state_change(cmap, cscr, fmt::format("State unset: {}", state_string));
1569
1570
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 471 times.
471 if((scr->nocarry&flag)!=flag)
1571 {
1572 471 byte nmap=TheMaps[((cmap)*MAPSCRS)+cscr].nextmap;
1573 471 byte nscr=TheMaps[((cmap)*MAPSCRS)+cscr].nextscr;
1574
1575 471 std::vector<int32_t> done;
1576
2/2
✓ Branch 0 taken 466 times.
✓ Branch 1 taken 5 times.
471 bool looped = (nmap==cmap+1 && nscr==cscr);
1577
1578
6/6
✓ Branch 0 taken 90 times.
✓ Branch 1 taken 465 times.
✓ Branch 2 taken 6 times.
✓ Branch 3 taken 84 times.
✓ Branch 4 taken 84 times.
✓ Branch 5 taken 471 times.
555 while((nmap!=0) && !looped && !(nscr>=128))
1579 {
1580
3/4
✓ Branch 0 taken 84 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✓ Branch 3 taken 72 times.
84 if(game->maps[((nmap-1)<<7)+nscr] & flag)
1581 {
1582
2/4
✓ Branch 0 taken 72 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 72 times.
✗ Branch 3 not taken.
72 log_state_change(nmap, nscr, "State change carried over");
1583
1/2
✓ Branch 0 taken 72 times.
✗ Branch 1 not taken.
72 game->maps[((nmap-1)<<7)+nscr] &= ~flag;
1584 72 }
1585
1586 84 cmap=nmap;
1587 84 cscr=nscr;
1588 84 nmap=TheMaps[((cmap-1)*MAPSCRS)+cscr].nextmap;
1589 84 nscr=TheMaps[((cmap-1)*MAPSCRS)+cscr].nextscr;
1590
1591
2/2
✓ Branch 0 taken 84 times.
✓ Branch 1 taken 546 times.
630 for(std::vector<int32_t>::iterator it = done.begin(); it != done.end(); it++)
1592 {
1593
2/2
✓ Branch 0 taken 540 times.
✓ Branch 1 taken 6 times.
546 if(*it == ((nmap-1)<<7)+nscr)
1594 6 looped = true;
1595 546 }
1596
1597
1/2
✓ Branch 0 taken 84 times.
✗ Branch 1 not taken.
84 done.push_back(((nmap-1)<<7)+nscr);
1598 }
1599 471 }
1600 471 }
1601
1602 51930729 bool getmapflag(int32_t screen, uint32_t flag)
1603 {
1604
2/2
✓ Branch 0 taken 1345925 times.
✓ Branch 1 taken 50584804 times.
51930729 int mi = mapind(cur_map, screen >= 0x80 ? home_screen : screen);
1605 51930729 return (game->maps[mi] & flag) != 0;
1606 }
1607 6409441 bool getmapflag(mapscr* scr, uint32_t flag)
1608 {
1609 6409441 return getmapflag(scr->screen, flag);
1610 }
1611
1612 57 void setxmapflag(int32_t screen, uint32_t flag)
1613 {
1614
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 57 times.
57 int mi = mapind(cur_map, screen >= 0x80 ? home_screen : screen);
1615 57 setxmapflag_mi(mi, flag);
1616 57 }
1617 59 void setxmapflag_mi(int32_t mi, uint32_t flag)
1618 {
1619
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 59 times.
59 if(game->xstates[mi] & flag) return;
1620 59 byte cscr = mi&((1<<7)-1);
1621 59 byte cmap = (mi>>7);
1622
1623 59 byte temp=(byte)log2((double)flag);
1624
1/2
✓ Branch 0 taken 59 times.
✗ Branch 1 not taken.
59 log_state_change(cmap, cscr, fmt::format("ExtraState set: {}", temp));
1625
1626 59 game->xstates[mi] |= flag;
1627
1628 59 mapscr* scr = origin_scr;
1629
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 59 times.
59 if (is_in_current_region(cmap, cscr))
1630 59 scr = get_scr(cmap, cscr);
1631
1632
1/2
✓ Branch 0 taken 59 times.
✗ Branch 1 not taken.
59 if((scr->exstate_carry&flag)==flag)
1633 {
1634 byte nmap=TheMaps[((cmap)*MAPSCRS)+cscr].nextmap;
1635 byte nscr=TheMaps[((cmap)*MAPSCRS)+cscr].nextscr;
1636
1637 std::vector<int32_t> done;
1638 bool looped = (nmap==cmap+1 && nscr==cscr);
1639
1640 while((nmap!=0) && !looped && !(nscr>=128))
1641 {
1642 if(!(game->maps[((nmap-1)<<7)+nscr] & flag))
1643 {
1644 log_state_change(nmap, nscr, "ExState change carried over");
1645 if (replay_is_active())
1646 replay_step_comment(fmt::format("map {} scr {} exstate {} carry", nmap, nscr, temp));
1647 game->xstates[((nmap-1)<<7)+nscr] |= flag;
1648 }
1649
1650 cmap=nmap;
1651 cscr=nscr;
1652 nmap=TheMaps[((cmap-1)*MAPSCRS)+cscr].nextmap;
1653 nscr=TheMaps[((cmap-1)*MAPSCRS)+cscr].nextscr;
1654
1655 for(auto it = done.begin(); it != done.end(); it++)
1656 {
1657 if(*it == ((nmap-1)<<7)+nscr)
1658 looped = true;
1659 }
1660
1661 done.push_back(((nmap-1)<<7)+nscr);
1662 }
1663 }
1664 59 }
1665 2 void unsetxmapflag(int32_t screen, uint32_t flag)
1666 {
1667
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 int mi = mapind(cur_map, screen >= 0x80 ? home_screen : screen);
1668 2 unsetxmapflag_mi(mi, flag);
1669 2 }
1670 2 void unsetxmapflag_mi(int32_t mi, uint32_t flag)
1671 {
1672
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
2 if(!(game->xstates[mi] & flag)) return;
1673 1 byte cscr = mi&((1<<7)-1);
1674 1 byte cmap = (mi>>7);
1675 1 byte temp=(byte)log2((double)flag);
1676
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 log_state_change(cmap, cscr, fmt::format("ExtraState unset: {}", temp));
1677 1 game->xstates[mi] &= ~flag;
1678
1679 1 mapscr* scr = origin_scr;
1680
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (is_in_current_region(cmap, cscr))
1681 1 scr = get_scr(cmap, cscr);
1682
1683
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if((scr->exstate_carry&flag)==flag)
1684 {
1685 byte nmap=TheMaps[((cmap)*MAPSCRS)+cscr].nextmap;
1686 byte nscr=TheMaps[((cmap)*MAPSCRS)+cscr].nextscr;
1687
1688 std::vector<int32_t> done;
1689 bool looped = (nmap==cmap+1 && nscr==cscr);
1690
1691 while((nmap!=0) && !looped && !(nscr>=128))
1692 {
1693 if(game->maps[((nmap-1)<<7)+nscr] & flag)
1694 {
1695 log_state_change(nmap, nscr, "ExState change carried over");
1696 game->xstates[((nmap-1)<<7)+nscr] &= ~flag;
1697 }
1698
1699 cmap=nmap;
1700 cscr=nscr;
1701 nmap=TheMaps[((cmap-1)*MAPSCRS)+cscr].nextmap;
1702 nscr=TheMaps[((cmap-1)*MAPSCRS)+cscr].nextscr;
1703
1704 for(std::vector<int32_t>::iterator it = done.begin(); it != done.end(); it++)
1705 {
1706 if(*it == ((nmap-1)<<7)+nscr)
1707 looped = true;
1708 }
1709
1710 done.push_back(((nmap-1)<<7)+nscr);
1711 }
1712 }
1713 2 }
1714 82 bool getxmapflag(int32_t screen, uint32_t flag)
1715 {
1716
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 82 times.
82 int mi = mapind(cur_map, screen >= 0x80 ? home_screen : screen);
1717 82 return getxmapflag_mi(mi, flag);
1718 }
1719 488377632 bool getxmapflag_mi(int32_t mi, uint32_t flag)
1720 {
1721 488377632 return (game->xstates[mi] & flag) != 0;
1722 }
1723
1724 4 void setxdoor_mi(uint mi, uint dir, uint ind, bool state)
1725 {
1726
3/6
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 4 times.
4 if(mi > game->xdoors.size() || dir > 3 || ind > 8)
1727 return;
1728
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 if(!(game->xdoors[mi][dir] & (1<<ind)) == !state)
1729 return;
1730
1731
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 SETFLAG(game->xdoors[mi][dir], 1<<ind, state);
1732
1733 4 int cscr = mi % MAPSCRSNORMAL;
1734 4 int cmap = mi / MAPSCRSNORMAL;
1735
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 if (state)
1736
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 log_state_change(cmap, cscr, fmt::format("ExDoor[{}][{}] set", dirstr[dir], ind));
1737 else
1738 log_state_change(cmap, cscr, fmt::format("ExDoor[{}][{}] unset", dirstr[dir], ind));
1739 4 }
1740 488377545 bool getxdoor_mi(uint mi, uint dir, uint ind)
1741 {
1742
3/6
✓ Branch 0 taken 488377545 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 488377545 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 488377545 times.
488377545 if(mi >= game->xdoors.size() || dir >= 4 || ind >= 8)
1743 return false;
1744 488377545 return (game->xdoors[mi][dir] & (1<<ind));
1745 488377545 }
1746 9 bool getxdoor(int32_t screen, uint dir, uint ind)
1747 {
1748 9 int mi = mapind(cur_map, screen);
1749 9 return getxdoor_mi(mi,dir,ind);
1750 }
1751
1752 401 void set_doorstate_mi(uint mi, uint dir)
1753 {
1754
1/2
✓ Branch 0 taken 401 times.
✗ Branch 1 not taken.
401 if(dir >= 4)
1755 return;
1756 401 setmapflag_mi(mi, mDOOR_UP << dir);
1757
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 400 times.
401 if(auto di = nextscr_mi(mi, dir))
1758 400 setmapflag_mi(*di, mDOOR_UP << oppositeDir[dir]);
1759 401 }
1760 401 void set_doorstate(uint screen, uint dir)
1761 {
1762 401 int mi = mapind(cur_map, screen);
1763 401 set_doorstate_mi(mi, dir);
1764 401 }
1765
1766 2 void set_xdoorstate_mi(uint mi, uint dir, uint ind, bool state)
1767 {
1768
3/6
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
2 if(mi >= game->xdoors.size() || dir >= 4 || ind >= 8)
1769 return;
1770 2 setxdoor_mi(mi, dir, ind, state);
1771
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if(auto di = nextscr_mi(mi, dir))
1772 2 setxdoor_mi(*di, oppositeDir[dir], ind, state);
1773 2 }
1774
1775 2 void set_xdoorstate(int32_t screen,uint dir, uint ind, bool state)
1776 {
1777 2 int mi = mapind(cur_map, screen);
1778 2 set_xdoorstate_mi(mi, dir, ind, state);
1779 2 }
1780
1781 57 int32_t WARPCODE(int32_t dmap,int32_t screen,int32_t dw)
1782 // returns: -1 = not a warp screen
1783 // 0+ = warp screen code ( high byte=dmap, low byte=scr )
1784 {
1785 57 const mapscr *scr = get_canonical_scr(DMaps[dmap].map, screen);
1786
1787
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 57 times.
57 if(scr->room!=rWARP)
1788 return -1;
1789
1790 57 int32_t ring=scr->catchall;
1791 57 int32_t size=QMisc.warp[ring].size;
1792
1793
1/2
✓ Branch 0 taken 57 times.
✗ Branch 1 not taken.
57 if(size==0)
1794 return -2;
1795
1796 57 int32_t index=-1;
1797
1798
2/2
✓ Branch 0 taken 289 times.
✓ Branch 1 taken 57 times.
346 for(int32_t i=0; i<size; i++)
1799
6/6
✓ Branch 0 taken 230 times.
✓ Branch 1 taken 59 times.
✓ Branch 2 taken 173 times.
✓ Branch 3 taken 57 times.
✓ Branch 4 taken 173 times.
✓ Branch 5 taken 57 times.
289 if(dmap==QMisc.warp[ring].dmap[i] && screen==
1800 346 (QMisc.warp[ring].scr[i] + DMaps[dmap].xoff))
1801 57 index=i;
1802
1803
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 57 times.
57 if(index==-1)
1804 return -3;
1805
1806 57 index = (index+dw)%size;
1807 57 return (QMisc.warp[ring].dmap[index] << 8) + QMisc.warp[ring].scr[index];
1808 57 }
1809
1810 15355948 void update_combo_cycling()
1811 {
1812 15355948 auto& combo_cache = combo_caches::can_cycle;
1813
1814 static int32_t newdata[176];
1815 static int32_t newcset[176];
1816 static bool initialized=false;
1817
1818 // Just a simple bit of optimization
1819
2/2
✓ Branch 0 taken 15355627 times.
✓ Branch 1 taken 321 times.
15355948 if(!initialized)
1820 {
1821
2/2
✓ Branch 0 taken 56496 times.
✓ Branch 1 taken 321 times.
56817 for(int32_t i=0; i<176; i++)
1822 {
1823 56496 newdata[i]=-1;
1824 56496 newcset[i]=-1;
1825 56496 }
1826
1827 321 initialized=true;
1828 321 }
1829
1830 15355948 std::set<uint16_t> restartanim;
1831
1832
1/2
✓ Branch 0 taken 15355948 times.
✗ Branch 1 not taken.
31101264 for_every_base_screen_in_region([&](mapscr* scr, unsigned int region_scr_x, unsigned int region_scr_y) {
1833 15745316 int screen = scr->screen;
1834 int32_t x;
1835
1836
2/2
✓ Branch 0 taken 2771175616 times.
✓ Branch 1 taken 15745316 times.
2786920932 for(int32_t i=0; i<176; i++)
1837 {
1838 2771175616 x=scr->data[i];
1839 2771175616 auto& mini_cmb = combo_cache.minis[x];
1840
2/2
✓ Branch 0 taken 3282224 times.
✓ Branch 1 taken 2767893392 times.
2771175616 if (!mini_cmb.can_cycle)
1841 2767893392 continue;
1842
1843 3282224 newcombo const& cmb = combobuf[x];
1844
1845 //time to restart
1846
4/4
✓ Branch 0 taken 904477 times.
✓ Branch 1 taken 2377747 times.
✓ Branch 2 taken 475770 times.
✓ Branch 3 taken 428707 times.
3282224 if ((cmb.aclk>=cmb.speed) && combocheck(cmb))
1847 {
1848 428707 bool cycle_under = (cmb.animflags & AF_CYCLEUNDERCOMBO);
1849
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 428707 times.
428707 auto c = cycle_under ? scr->undercombo : cmb.nextcombo;
1850 428707 newdata[i] = c;
1851
2/2
✓ Branch 0 taken 20 times.
✓ Branch 1 taken 428687 times.
428707 if(!(cmb.animflags & AF_CYCLENOCSET))
1852
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 428687 times.
428687 newcset[i] = cycle_under ? scr->undercset : cmb.nextcset;
1853
1854
2/2
✓ Branch 0 taken 427663 times.
✓ Branch 1 taken 1044 times.
428707 if(combobuf[c].animflags & AF_CYCLE)
1855 {
1856 1044 restartanim.insert(c);
1857 1044 }
1858 428707 }
1859 3282224 }
1860
1861 15745316 int rpos_base = (int)POS_TO_RPOS(0, region_scr_x, region_scr_y);
1862
2/2
✓ Branch 0 taken 2771175616 times.
✓ Branch 1 taken 15745316 times.
2786920932 for(int32_t i=0; i<176; i++)
1863 {
1864
2/2
✓ Branch 0 taken 428707 times.
✓ Branch 1 taken 2770746909 times.
2771175616 if(newdata[i]==-1)
1865 2770746909 continue;
1866
1867 428707 rpos_t rpos = (rpos_t)(rpos_base + i);
1868 428707 rpos_handle_t rpos_handle = {scr, screen, 0, rpos, i};
1869 428707 screen_combo_modify_preroutine(rpos_handle);
1870 428707 scr->data[i]=newdata[i];
1871
2/2
✓ Branch 0 taken 20 times.
✓ Branch 1 taken 428687 times.
428707 if(newcset[i]>-1)
1872 428687 scr->cset[i]=newcset[i];
1873 428707 screen_combo_modify_postroutine(rpos_handle);
1874
1875 428707 newdata[i]=-1;
1876 428707 newcset[i]=-1;
1877 428707 }
1878
1879 15745316 word c = scr->numFFC();
1880
2/2
✓ Branch 0 taken 15745316 times.
✓ Branch 1 taken 454715631 times.
470460947 for(word i=0; i<c; i++)
1881 {
1882 454715631 ffcdata& ffc = scr->ffcs[i];
1883 454715631 auto& mini_cmb = combo_cache.minis[ffc.data];
1884
2/2
✓ Branch 0 taken 7727 times.
✓ Branch 1 taken 454707904 times.
454715631 if (!mini_cmb.can_cycle)
1885 454707904 continue;
1886
1887 7727 newcombo const& cmb = combobuf[ffc.data];
1888
1889 //time to restart
1890
4/4
✓ Branch 0 taken 1181 times.
✓ Branch 1 taken 6546 times.
✓ Branch 2 taken 856 times.
✓ Branch 3 taken 325 times.
7727 if ((cmb.aclk>=cmb.speed) && combocheck(cmb))
1891 {
1892 325 bool cycle_under = (cmb.animflags & AF_CYCLEUNDERCOMBO);
1893
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 325 times.
325 auto c = cycle_under ? scr->undercombo : cmb.nextcombo;
1894 325 zc_ffc_set(ffc, c);
1895
2/2
✓ Branch 0 taken 217 times.
✓ Branch 1 taken 108 times.
325 if(!(cmb.animflags & AF_CYCLENOCSET))
1896
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 108 times.
108 ffc.cset = cycle_under ? scr->undercset : cmb.nextcset;
1897
1898
2/2
✓ Branch 0 taken 265 times.
✓ Branch 1 taken 60 times.
325 if(combobuf[ffc.data].animflags & AF_CYCLE)
1899 {
1900 60 restartanim.insert(ffc.data);
1901 60 }
1902 325 }
1903 7727 }
1904
1905
2/2
✓ Branch 0 taken 8418399 times.
✓ Branch 1 taken 7326917 times.
15745316 if(get_qr(qr_CMBCYCLELAYERS))
1906 {
1907
2/2
✓ Branch 0 taken 43961502 times.
✓ Branch 1 taken 7326917 times.
51288419 for(int32_t j=1; j<=6; j++)
1908 {
1909 43961502 mapscr* layer_scr = get_scr_layer_valid(screen, j);
1910
2/2
✓ Branch 0 taken 13893876 times.
✓ Branch 1 taken 30067626 times.
43961502 if (!layer_scr)
1911 30067626 continue;
1912
1913
2/2
✓ Branch 0 taken 2445322176 times.
✓ Branch 1 taken 13893876 times.
2459216052 for(int32_t i=0; i<176; i++)
1914 {
1915 2445322176 x=layer_scr->data[i];
1916 2445322176 auto& mini_cmb = combo_cache.minis[x];
1917
2/2
✓ Branch 0 taken 2424344 times.
✓ Branch 1 taken 2442897832 times.
2445322176 if (!mini_cmb.can_cycle)
1918 2442897832 continue;
1919
1920 2424344 newcombo const& cmb = combobuf[x];
1921
1922 //time to restart
1923
4/4
✓ Branch 0 taken 67298 times.
✓ Branch 1 taken 2357046 times.
✓ Branch 2 taken 50626 times.
✓ Branch 3 taken 16672 times.
2424344 if ((cmb.aclk>=cmb.speed) && combocheck(cmb))
1924 {
1925 16672 bool cycle_under = (cmb.animflags & AF_CYCLEUNDERCOMBO);
1926
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16672 times.
16672 auto c = cycle_under ? layer_scr->undercombo : cmb.nextcombo;
1927 16672 newdata[i] = c;
1928
2/2
✓ Branch 0 taken 644 times.
✓ Branch 1 taken 16028 times.
16672 if(!(cmb.animflags & AF_CYCLENOCSET))
1929
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16028 times.
16028 newcset[i] = cycle_under ? layer_scr->undercset : cmb.nextcset;
1930 644 else newcset[i] = layer_scr->cset[i];
1931
1932
2/2
✓ Branch 0 taken 6689 times.
✓ Branch 1 taken 9983 times.
16672 if(combobuf[c].animflags & AF_CYCLE)
1933 {
1934 9983 restartanim.insert(c);
1935 9983 }
1936 16672 }
1937 2424344 }
1938
1939
2/2
✓ Branch 0 taken 2445322176 times.
✓ Branch 1 taken 13893876 times.
2459216052 for (int32_t i=0; i<176; i++)
1940 {
1941
2/2
✓ Branch 0 taken 2445305504 times.
✓ Branch 1 taken 16672 times.
2445322176 if(newdata[i]!=-1)
1942 {
1943 16672 layer_scr->data[i]=newdata[i];
1944
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16672 times.
16672 if(newcset[i]>-1)
1945 16672 layer_scr->cset[i]=newcset[i];
1946 16672 newdata[i]=-1;
1947 16672 newcset[i]=-1;
1948 16672 }
1949 2445322176 }
1950 13893876 }
1951 7326917 }
1952 15745316 });
1953
1954
2/2
✓ Branch 0 taken 15355948 times.
✓ Branch 1 taken 2661 times.
15358609 for (auto i : restartanim)
1955 {
1956 2661 combobuf[i].tile = combobuf[i].o_tile;
1957 2661 combobuf[i].cur_frame=0;
1958 2661 combobuf[i].aclk = 0;
1959
1/2
✓ Branch 0 taken 2661 times.
✗ Branch 1 not taken.
2661 combo_caches::drawing.refresh(i);
1960 }
1961 15355948 }
1962
1963 1425977577 bool iswater_type(int32_t type)
1964 {
1965 // return type==cOLD_WATER || type==cSWIMWARP || type==cDIVEWARP || type==cDIVEWARPB || type==cDIVEWARPC || type==cDIVEWARPD || type==cSWIMWARPB || type==cSWIMWARPC || type==cSWIMWARPD;
1966 1425977577 return (combo_class_buf[type].water!=0);
1967 }
1968
1969 bool iswater(int32_t combo)
1970 {
1971 return iswater_type(combobuf[combo].type) && !DRIEDLAKE;
1972 }
1973 5280776 int32_t iswaterexzq(int32_t combo, int32_t map, int32_t screen, int32_t layer, int32_t x, int32_t y, bool secrets, bool fullcheck, bool LayerCheck)
1974 {
1975 5280776 return iswaterex(combo, map, screen, layer, x, y, secrets, fullcheck, LayerCheck);
1976 }
1977
1978 // (x, y) are world coordinates
1979 68226351 int32_t iswaterex_z3(int32_t combo, int32_t layer, int32_t x, int32_t y, bool secrets, bool fullcheck, bool LayerCheck, bool ShallowCheck, bool hero, optional<combined_handle_t>* out_handle)
1980 {
1981
8/8
✓ Branch 0 taken 68178488 times.
✓ Branch 1 taken 47863 times.
✓ Branch 2 taken 68136628 times.
✓ Branch 3 taken 41860 times.
✓ Branch 4 taken 68067145 times.
✓ Branch 5 taken 69483 times.
✓ Branch 6 taken 63405 times.
✓ Branch 7 taken 68003740 times.
68226351 if (x<0 || x>=world_w || y<0 || y>=world_h)
1982 222611 return false;
1983
1984 68003740 return iswaterex(combo, cur_map, cur_screen, layer, x, y, secrets, fullcheck, LayerCheck, ShallowCheck, hero, out_handle);
1985 68226351 }
1986
1987 148644714 int32_t iswaterex(int32_t combo, int32_t map, int32_t screen, int32_t layer, int32_t x, int32_t y, bool secrets, bool fullcheck, bool LayerCheck, bool ShallowCheck, bool hero, optional<combined_handle_t>* out_handle)
1988 {
1989 DCHECK_LAYER_NEG1_INDEX(layer);
1990 //Honestly, fullcheck is kinda useless... I made this function back when I thought it was checking the entire combo and not just a glorified x/y value.
1991 //Fullcheck makes no sense to ever be on, but hey I guess it's here in case you ever need it...
1992
1993 //Oh hey, Zoras might actually need it. Nevermind, this had a use!
1994
2/2
✓ Branch 0 taken 108731341 times.
✓ Branch 1 taken 39913373 times.
148644714 if (get_qr(qr_SMARTER_WATER))
1995 {
1996
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 108731341 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
108731341 if (DRIEDLAKE) return 0;
1997
5/6
✓ Branch 0 taken 32436494 times.
✓ Branch 1 taken 76294847 times.
✓ Branch 2 taken 6533834 times.
✓ Branch 3 taken 25902660 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 6533834 times.
108731341 if (LayerCheck && (get_qr(qr_WATER_ON_LAYER_1) || get_qr(qr_WATER_ON_LAYER_2))) //LayerCheck is a bit dumber, but it lets me add this QR without having to replace all calls, again.
1998 {
1999
2/2
✓ Branch 0 taken 75536388 times.
✓ Branch 1 taken 24812647 times.
100349035 for (int32_t m = layer; m <= 1; m++)
2000 {
2001
5/6
✓ Branch 0 taken 49633728 times.
✓ Branch 1 taken 25902660 times.
✓ Branch 2 taken 24819862 times.
✓ Branch 3 taken 24813866 times.
✓ Branch 4 taken 24813866 times.
✗ Branch 5 not taken.
100350254 if (m < 0 || m == 0 && get_qr(qr_WATER_ON_LAYER_1)
2002
1/2
✓ Branch 0 taken 24813866 times.
✗ Branch 1 not taken.
49633728 || m == 1 && get_qr(qr_WATER_ON_LAYER_2))
2003 {
2004 75536388 int32_t checkwater = iswaterex(combo, map, screen, m, x, y, secrets, fullcheck, false, ShallowCheck);
2005
2/2
✓ Branch 0 taken 74446375 times.
✓ Branch 1 taken 1090013 times.
75536388 if (checkwater > 0)
2006 {
2007
2/2
✓ Branch 0 taken 1089930 times.
✓ Branch 1 taken 83 times.
1090013 if(out_handle) *out_handle = get_rpos_handle_for_world_xy(x, y, m+1);
2008 1090013 return checkwater;
2009 }
2010 74446375 }
2011 74446375 }
2012 24812647 return 0;
2013 }
2014 else
2015 {
2016
2/2
✓ Branch 0 taken 82852325 times.
✓ Branch 1 taken 78300666 times.
161152991 for(int32_t i=(fullcheck?3:0); i>=0; i--)
2017 {
2018 82852325 int32_t tx2=((i&2)<<2)+x;
2019 82852325 int32_t ty2=((i&1)<<3)+y;
2020 82852325 int32_t b = i; //Originally b was not needed and I read off i, but then I added the boolean for fullcheck.
2021 //In which case it's just easier to change b if fullcheck is false instead of changing i and potentially screwing up the for loop.
2022
2/2
✓ Branch 0 taken 36073 times.
✓ Branch 1 taken 82816252 times.
82852325 if (!fullcheck)
2023 {
2024 82816252 tx2 = x;
2025 82816252 ty2 = y;
2026
2/2
✓ Branch 0 taken 45301559 times.
✓ Branch 1 taken 37514693 times.
82816252 if(tx2&8) b+=2;
2027
2/2
✓ Branch 0 taken 39266539 times.
✓ Branch 1 taken 43549713 times.
82816252 if(ty2&8) b+=1;
2028 82816252 }
2029
2/2
✓ Branch 0 taken 171675641 times.
✓ Branch 1 taken 80408910 times.
252084551 for (int32_t m = layer; m <= 1; m++)
2030 {
2031 171675641 newcombo const& cmb = combobuf[MAPCOMBO3(map, screen, m,tx2,ty2, true)];
2032
3/6
✓ Branch 0 taken 169488138 times.
✓ Branch 1 taken 2187503 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 169488138 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
171675641 if (hero && cmb.dive_under_level && (Hero.get_standing_z_state() <= -cmb.dive_under_level))
2033 continue; // dive under this layer
2034
2035
2/2
✓ Branch 0 taken 17728431 times.
✓ Branch 1 taken 153947210 times.
171675641 if (get_qr(qr_OLD_BRIDGE_COMBOS))
2036 {
2037
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 17728431 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
17728431 if (cmb.type == cBRIDGE && !(cmb.walk&(1<<b)))
2038 {
2039 return 0;
2040 }
2041 17728431 }
2042 else
2043 {
2044
4/4
✓ Branch 0 taken 253102 times.
✓ Branch 1 taken 153694108 times.
✓ Branch 2 taken 51152 times.
✓ Branch 3 taken 201950 times.
153947210 if (cmb.type == cBRIDGE && (cmb.walk&(0x10<<b)))
2045 {
2046 201950 return 0;
2047 }
2048 }
2049
2/2
✓ Branch 0 taken 17728431 times.
✓ Branch 1 taken 153745260 times.
171473691 if (get_qr(qr_NO_SOLID_SWIM))
2050 {
2051
8/14
✓ Branch 0 taken 51152 times.
✓ Branch 1 taken 153694108 times.
✓ Branch 2 taken 51152 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2241465 times.
✓ Branch 5 taken 151452643 times.
✓ Branch 6 taken 34499 times.
✓ Branch 7 taken 2206966 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 34499 times.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
153745260 if ((cmb.type != cBRIDGE || (!get_qr(qr_OLD_BRIDGE_COMBOS) && !(cmb.walk&(0x10<<b)))) && (cmb.walk&(1<<b)) && !((cmb.usrflags&cflag4) && cmb.type == cWATER && (cmb.walk&(0x10<<b)) && ShallowCheck))
2052 2241465 return 0;
2053 151503795 }
2054
3/6
✓ Branch 0 taken 497938 times.
✓ Branch 1 taken 168734288 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 497938 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
169232226 if (iswater_type(cmb.type) && (cmb.walk&(1<<b)) && ((cmb.usrflags&cflag3) || (cmb.usrflags&cflag4)
2055 || (hero && current_item(itype_flippers) < cmb.attribytes[0])
2056 || (hero && ((cmb.usrflags&cflag1) && !(itemsbuf[current_item_id(itype_flippers)].flags & item_flag3)))))
2057 {
2058 if (!(ShallowCheck && (cmb.walk&(1<<b)) && (cmb.usrflags&cflag4))) return 0;
2059 }
2060 169232226 }
2061
2062 223172607 auto found_ffc_not_water = find_ffc([&](const ffc_handle_t& ffc_handle) {
2063
2/2
✓ Branch 0 taken 141976906 times.
✓ Branch 1 taken 786791 times.
142763697 if (ffcIsAt(ffc_handle, tx2, ty2))
2064 {
2065 786791 auto ty = ffc_handle.ctype();
2066
4/6
✓ Branch 0 taken 786791 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 193850 times.
✓ Branch 3 taken 592941 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 193850 times.
786791 if(!combo_class_buf[ty].water && !(ShallowCheck && ty == cSHALLOWWATER))
2067 786791 return true;
2068 }
2069
2070 141976906 return false;
2071 142763697 });
2072
2/2
✓ Branch 0 taken 79622119 times.
✓ Branch 1 taken 786791 times.
80408910 if (found_ffc_not_water) return 0;
2073
2074
2/2
✓ Branch 0 taken 23644 times.
✓ Branch 1 taken 79598475 times.
79622119 if(!i)
2075 {
2076 219064167 auto found_ffc_water = find_ffc([&](const ffc_handle_t& ffc_handle) {
2077
1/2
✓ Branch 0 taken 139465692 times.
✗ Branch 1 not taken.
139465692 if (ffcIsAt(ffc_handle, tx2, ty2))
2078 {
2079 auto ty = ffc_handle.ctype();
2080 if(combo_class_buf[ty].water || (ShallowCheck && ty == cSHALLOWWATER))
2081 return true;
2082 }
2083
2084 139465692 return false;
2085 139465692 });
2086
1/2
✓ Branch 0 taken 79598475 times.
✗ Branch 1 not taken.
79598475 if (found_ffc_water)
2087 {
2088 if(out_handle) *out_handle = *found_ffc_water;
2089 return found_ffc_water->data();
2090 }
2091 79598475 }
2092
2093 79622119 int32_t checkcombo = MAPCOMBO3(map, screen, layer, tx2, ty2, secrets);
2094
2/2
✓ Branch 0 taken 79577625 times.
✓ Branch 1 taken 44494 times.
79622119 if (!(combobuf[checkcombo].walk&(1<<(b+4)))) return 0;
2095
7/12
✓ Branch 0 taken 79147603 times.
✓ Branch 1 taken 430022 times.
✓ Branch 2 taken 16998892 times.
✓ Branch 3 taken 62148711 times.
✓ Branch 4 taken 16174022 times.
✓ Branch 5 taken 824870 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 16174022 times.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
79577625 if (iswater_type(combobuf[checkcombo].type)||(ShallowCheck && (combobuf[checkcombo].type == cSHALLOWWATER || (iswater_type(combobuf[checkcombo].type) && (combobuf[checkcombo].walk&(1<<b)) && (combobuf[checkcombo].usrflags&cflag4)))))
2096 {
2097
2/2
✓ Branch 0 taken 1577 times.
✓ Branch 1 taken 1253315 times.
1254892 if (i == 0)
2098 {
2099
2/2
✓ Branch 0 taken 1253306 times.
✓ Branch 1 taken 9 times.
1253315 if(out_handle) *out_handle = get_rpos_handle_for_world_xy(tx2, ty2, layer+1);
2100 1253315 return checkcombo;
2101 }
2102 1577 }
2103 78324310 }
2104 78300666 return 0;
2105 }
2106 }
2107 else
2108 {
2109 39913373 int32_t b = 0;
2110
2/2
✓ Branch 0 taken 20700324 times.
✓ Branch 1 taken 19213049 times.
39913373 if(x&8) b+=2;
2111
2/2
✓ Branch 0 taken 15520397 times.
✓ Branch 1 taken 24392976 times.
39913373 if(y&8) b+=1;
2112
1/2
✓ Branch 0 taken 39913373 times.
✗ Branch 1 not taken.
39913373 if (get_qr(qr_NO_SOLID_SWIM))
2113 {
2114 if (combobuf[combo].walk&(1<<b))
2115 {
2116 return 0;
2117 }
2118 }
2119
1/2
✓ Branch 0 taken 39913373 times.
✗ Branch 1 not taken.
39913373 if (!(combobuf[combo].walk&(1<<(b+4)))) return 0;
2120
8/8
✓ Branch 0 taken 38150901 times.
✓ Branch 1 taken 1762472 times.
✓ Branch 2 taken 167945 times.
✓ Branch 3 taken 37982956 times.
✓ Branch 4 taken 2129 times.
✓ Branch 5 taken 1778552 times.
✓ Branch 6 taken 163774 times.
✓ Branch 7 taken 165477 times.
39913373 if((iswater_type(combobuf[combo].type) || (ShallowCheck && combobuf[combo].type == cSHALLOWWATER)) && !DRIEDLAKE)
2121 {
2122
2/2
✓ Branch 0 taken 1943999 times.
✓ Branch 1 taken 30 times.
1944029 if(out_handle) *out_handle = get_rpos_handle_for_world_xy(x, y, 0); //NOTE: This is only correct assuming 'combo' is 'MAPCOMBO(x,y)'
2123 1944029 return combo;
2124 }
2125 38146730 return 0;
2126 }
2127 148822100 }
2128
2129 354 bool isdamage_type(int32_t type)
2130 {
2131
2/2
✓ Branch 0 taken 326 times.
✓ Branch 1 taken 28 times.
354 switch(type)
2132 {
2133 case cDAMAGE1: case cDAMAGE2: case cDAMAGE3: case cDAMAGE4:
2134 case cDAMAGE5: case cDAMAGE6: case cDAMAGE7:
2135 28 return true;
2136 }
2137 326 return false;
2138 354 }
2139
2140 2230718524 bool ispitfall_type(int32_t type)
2141 {
2142 2230718524 return combo_class_buf[type].pit != 0;
2143 }
2144
2145 2230718524 bool ispitfall(int32_t combo)
2146 {
2147 2230718524 return ispitfall_type(combobuf[combo].type);
2148 }
2149
2150 138851793 bool ispitfall(int32_t x, int32_t y)
2151 {
2152
2/2
✓ Branch 0 taken 1303540 times.
✓ Branch 1 taken 137548253 times.
138851793 if(int32_t c = MAPFFCOMBO(x,y))
2153 {
2154 1303540 return ispitfall(c) ? true : false;
2155 }
2156 137548253 int32_t c = MAPCOMBOL(2,x,y);
2157
2/2
✓ Branch 0 taken 77 times.
✓ Branch 1 taken 137548176 times.
137548253 if(ispitfall(c)) return true;
2158
2/2
✓ Branch 0 taken 122656443 times.
✓ Branch 1 taken 14891733 times.
137548176 if (get_qr(qr_OLD_BRIDGE_COMBOS))
2159 {
2160
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 122656443 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
122656443 if (combobuf[MAPCOMBO2(1,x,y)].type == cBRIDGE && !_walkflag_layer(x,y,1)) return false;
2161 122656443 }
2162 else
2163 {
2164
3/4
✓ Branch 0 taken 16383 times.
✓ Branch 1 taken 14875350 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 16383 times.
14891733 if (combobuf[MAPCOMBO2(1,x,y)].type == cBRIDGE && _effectflag_layer(x,y,1)) return false;
2165 }
2166 137531793 c = MAPCOMBOL(1,x,y);
2167
2/2
✓ Branch 0 taken 19968 times.
✓ Branch 1 taken 137511825 times.
137531793 if(ispitfall(c)) return true;
2168
2169
2/2
✓ Branch 0 taken 122656443 times.
✓ Branch 1 taken 14855382 times.
137511825 if (get_qr(qr_OLD_BRIDGE_COMBOS))
2170 {
2171
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 122656443 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
122656443 if (combobuf[MAPCOMBO2(0,x,y)].type == cBRIDGE && !_walkflag_layer(x,y,0)) return false;
2172 122656443 }
2173 else
2174 {
2175
4/4
✓ Branch 0 taken 16533 times.
✓ Branch 1 taken 14838849 times.
✓ Branch 2 taken 12238 times.
✓ Branch 3 taken 4295 times.
14855382 if (combobuf[MAPCOMBO2(0,x,y)].type == cBRIDGE && _effectflag_layer(x,y,0)) return false;
2176 }
2177 137499587 c = MAPCOMBO(x,y);
2178
2/2
✓ Branch 0 taken 59028 times.
✓ Branch 1 taken 137440559 times.
137499587 if(ispitfall(c)) return true;
2179 137440559 return false;
2180 138851793 }
2181
2182 612042535 int32_t getpitfall(int32_t x, int32_t y) //Return the highest-layer active pit combo at the given position
2183 {
2184
2/2
✓ Branch 0 taken 9485176 times.
✓ Branch 1 taken 602557359 times.
612042535 if(int32_t c = MAPFFCOMBO(x,y))
2185 {
2186
2/2
✓ Branch 0 taken 845 times.
✓ Branch 1 taken 9484331 times.
9485176 return ispitfall(c) ? c : 0;
2187 }
2188 602557359 int32_t c = MAPCOMBOL(2,x,y);
2189
2/2
✓ Branch 0 taken 1362 times.
✓ Branch 1 taken 602555997 times.
602557359 if(ispitfall(c)) return c;
2190
2191
2/2
✓ Branch 0 taken 532722485 times.
✓ Branch 1 taken 69833512 times.
602555997 if (get_qr(qr_OLD_BRIDGE_COMBOS))
2192 {
2193
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 532722485 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
532722485 if (combobuf[MAPCOMBO2(1,x,y)].type == cBRIDGE && !_walkflag_layer(x,y,1)) return 0;
2194 532722485 }
2195 else
2196 {
2197
3/4
✓ Branch 0 taken 81755 times.
✓ Branch 1 taken 69751757 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 81755 times.
69833512 if (combobuf[MAPCOMBO2(1,x,y)].type == cBRIDGE && _effectflag_layer(x,y,1)) return 0;
2198 }
2199 602474242 c = MAPCOMBOL(1,x,y);
2200
2/2
✓ Branch 0 taken 25192 times.
✓ Branch 1 taken 602449050 times.
602474242 if(ispitfall(c)) return c;
2201
2202
2/2
✓ Branch 0 taken 532722485 times.
✓ Branch 1 taken 69726565 times.
602449050 if (get_qr(qr_OLD_BRIDGE_COMBOS))
2203 {
2204
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 532722485 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
532722485 if (combobuf[MAPCOMBO2(0,x,y)].type == cBRIDGE && !_walkflag_layer(x,y,0)) return 0;
2205 532722485 }
2206 else
2207 {
2208
4/4
✓ Branch 0 taken 171385 times.
✓ Branch 1 taken 69555180 times.
✓ Branch 2 taken 130757 times.
✓ Branch 3 taken 40628 times.
69726565 if (combobuf[MAPCOMBO2(0,x,y)].type == cBRIDGE && _effectflag_layer(x,y,0)) return 0;
2209 }
2210 602318293 c = MAPCOMBO(x,y);
2211
2/2
✓ Branch 0 taken 200737 times.
✓ Branch 1 taken 602117556 times.
602318293 if(ispitfall(c)) return c;
2212 602117556 return 0;
2213 612042535 }
2214 99 optional<combined_handle_t> get_pitfall_handle(int32_t x, int32_t y) //Return the highest-layer active pit combo handle at the given position
2215 {
2216
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 98 times.
99 if(int32_t c = MAPFFCOMBO(x,y))
2217 {
2218
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 return ispitfall(c) ? getFFCAt(x,y) : nullopt;
2219 }
2220 98 int32_t c = MAPCOMBOL(2,x,y);
2221
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 97 times.
98 if(ispitfall(c)) return get_rpos_handle_for_world_xy(x, y, 2);
2222
2223
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 91 times.
97 if (get_qr(qr_OLD_BRIDGE_COMBOS))
2224 {
2225
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
6 if (combobuf[MAPCOMBO2(1,x,y)].type == cBRIDGE && !_walkflag_layer(x,y,1))
2226 return nullopt;
2227 6 }
2228 else
2229 {
2230
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 91 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
91 if (combobuf[MAPCOMBO2(1,x,y)].type == cBRIDGE && _effectflag_layer(x,y,1))
2231 return nullopt;
2232 }
2233 97 c = MAPCOMBOL(1,x,y);
2234
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 85 times.
97 if(ispitfall(c)) return get_rpos_handle_for_world_xy(x, y, 1);
2235
2236
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 79 times.
85 if (get_qr(qr_OLD_BRIDGE_COMBOS))
2237 {
2238
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
6 if (combobuf[MAPCOMBO2(0,x,y)].type == cBRIDGE && !_walkflag_layer(x,y,0))
2239 return nullopt;
2240 6 }
2241 else
2242 {
2243
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 79 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
79 if (combobuf[MAPCOMBO2(0,x,y)].type == cBRIDGE && _effectflag_layer(x,y,0))
2244 return nullopt;
2245 }
2246 85 c = MAPCOMBO(x,y);
2247
1/2
✓ Branch 0 taken 85 times.
✗ Branch 1 not taken.
85 if(ispitfall(c)) return get_rpos_handle_for_world_xy(x, y, 0);
2248 return nullopt;
2249 99 }
2250 11916027 bool check_icy(newcombo const& cmb, int type)
2251 {
2252
2/2
✓ Branch 0 taken 11915862 times.
✓ Branch 1 taken 165 times.
11916027 if(cmb.type != cICY)
2253 11915862 return false;
2254
1/3
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✓ Branch 2 taken 165 times.
165 switch(type)
2255 {
2256 case ICY_BLOCK:
2257 return cmb.usrflags&cflag1;
2258 case ICY_PLAYER:
2259 165 return cmb.usrflags&cflag2;
2260 }
2261 return false;
2262 11916027 }
2263 3977959 int get_icy(int x, int y, int type)
2264 {
2265 3977959 int32_t c = MAPCOMBOL(2,x,y);
2266
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3977959 times.
3977959 if(check_icy(combobuf[c], type)) return c;
2267
2268 3977959 int screen = get_screen_for_world_xy(x, y);
2269
2270 3977959 mapscr* scr = get_scr_layer_valid(screen, 2);
2271
2/2
✓ Branch 0 taken 33173 times.
✓ Branch 1 taken 3944786 times.
3977959 if (scr)
2272 {
2273
2/2
✓ Branch 0 taken 516 times.
✓ Branch 1 taken 3944270 times.
3944786 if (get_qr(qr_OLD_BRIDGE_COMBOS))
2274 {
2275
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 516 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
516 if (combobuf[MAPCOMBO2(1,x,y)].type == cBRIDGE && !_walkflag_layer(x,y,1, scr)) return 0;
2276 516 }
2277 else
2278 {
2279
3/4
✓ Branch 0 taken 6663 times.
✓ Branch 1 taken 3937607 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 6663 times.
3944270 if (combobuf[MAPCOMBO2(1,x,y)].type == cBRIDGE && _effectflag_layer(x,y,1, scr)) return 0;
2280 }
2281 3938123 }
2282 3971296 c = MAPCOMBOL(1,x,y);
2283
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3971296 times.
3971296 if(check_icy(combobuf[c], type)) return c;
2284
2285 3971296 scr = get_scr_layer_valid(screen, 1);
2286
2/2
✓ Branch 0 taken 15312 times.
✓ Branch 1 taken 3955984 times.
3971296 if (scr)
2287 {
2288
2/2
✓ Branch 0 taken 1934 times.
✓ Branch 1 taken 3954050 times.
3955984 if (get_qr(qr_OLD_BRIDGE_COMBOS))
2289 {
2290
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 1934 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
1934 if (combobuf[MAPCOMBO2(0,x,y)].type == cBRIDGE && !_walkflag_layer(x,y,1, scr)) return 0;
2291 1934 }
2292 else
2293 {
2294
3/4
✓ Branch 0 taken 4689 times.
✓ Branch 1 taken 3949361 times.
✓ Branch 2 taken 4689 times.
✗ Branch 3 not taken.
3954050 if (combobuf[MAPCOMBO2(0,x,y)].type == cBRIDGE && _effectflag_layer(x,y,1, scr)) return 0;
2295 }
2296 3951295 }
2297 3966607 c = MAPCOMBO(x,y);
2298
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3966607 times.
3966607 if(check_icy(combobuf[c], type)) return c;
2299 3966607 return 0;
2300 3977959 }
2301
2302 13255439 static bool checkSV(int32_t x, int32_t y, int32_t flag)
2303 {
2304
8/8
✓ Branch 0 taken 13248641 times.
✓ Branch 1 taken 6798 times.
✓ Branch 2 taken 13239775 times.
✓ Branch 3 taken 8866 times.
✓ Branch 4 taken 13228143 times.
✓ Branch 5 taken 11632 times.
✓ Branch 6 taken 434748 times.
✓ Branch 7 taken 12793395 times.
13255439 if(x<0 || x>=world_w || y<0 || y>=world_h)
2305 462044 return false;
2306
2307 12793395 auto rpos_handle = get_rpos_handle_for_world_xy(x, y, 0);
2308
2/4
✓ Branch 0 taken 12793395 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 12793395 times.
12793395 if (rpos_handle.sflag() == flag || rpos_handle.cflag() == flag)
2309 return true;
2310
2311 12793395 change_rpos_handle_layer(rpos_handle, 1);
2312
2/2
✓ Branch 0 taken 7566118 times.
✓ Branch 1 taken 5227277 times.
12793395 if (rpos_handle.scr->is_valid())
2313
3/4
✓ Branch 0 taken 5227277 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3279 times.
✓ Branch 3 taken 5223998 times.
5227277 if (rpos_handle.sflag() == flag || rpos_handle.cflag() == flag)
2314 3279 return true;
2315
2316 12790116 change_rpos_handle_layer(rpos_handle, 2);
2317
2/2
✓ Branch 0 taken 10849920 times.
✓ Branch 1 taken 1940196 times.
12790116 if (rpos_handle.scr->is_valid())
2318
3/4
✓ Branch 0 taken 1940196 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 81 times.
✓ Branch 3 taken 1940115 times.
1940196 if (rpos_handle.sflag() == flag || rpos_handle.cflag() == flag)
2319 81 return true;
2320
2321 12790035 return false;
2322 13255439 }
2323
2324 6691902 bool isSVLadder(int32_t x, int32_t y)
2325 {
2326 6691902 return checkSV(x, y, mfSIDEVIEWLADDER);
2327 }
2328
2329 6563537 bool isSVPlatform(int32_t x, int32_t y)
2330 {
2331 6563537 return checkSV(x, y, mfSIDEVIEWPLATFORM);
2332 }
2333
2334 6563537 bool checkSVLadderPlatform(int32_t x, int32_t y)
2335 {
2336
3/4
✗ Branch 0 not taken.
✓ Branch 1 taken 6563537 times.
✓ Branch 2 taken 6561699 times.
✓ Branch 3 taken 1838 times.
6563537 return isSVPlatform(x,y) || (isSVLadder(x,y) && !isSVLadder(x,y-16));
2337 }
2338
2339 4206 bool isstepable(int32_t combo) //can use ladder on it
2340 {
2341
2/2
✓ Branch 0 taken 4200 times.
✓ Branch 1 taken 6 times.
4206 if(combo_class_buf[combobuf[combo].type].ladder_pass) return true;
2342
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 if(combo_class_buf[combobuf[combo].type].pit)
2343 {
2344 if(combobuf[combo].usrflags&cflag4)
2345 {
2346 int32_t ldrid = current_item_id(itype_ladder);
2347 return (ldrid > -1 && itemsbuf[ldrid].flags & item_flag1);
2348 }
2349 }
2350 6 return false;
2351 4206 }
2352
2353 33016 bool isHSGrabbable(newcombo const& cmb)
2354 {
2355
2/2
✓ Branch 0 taken 377 times.
✓ Branch 1 taken 32639 times.
33016 if(cmb.type == cHSGRAB) return true;
2356 32639 return cmb.genflags & cflag1;
2357 33016 }
2358
2359 954 bool isSwitchHookable(newcombo const& cmb)
2360 {
2361
2/2
✓ Branch 0 taken 132 times.
✓ Branch 1 taken 822 times.
954 if(cmb.type == cSWITCHHOOK) return true;
2362 822 return cmb.genflags & cflag2;
2363 954 }
2364
2365 62207 bool check_hshot(int32_t layer, int32_t x, int32_t y, bool switchhook, rpos_t *out_rpos, ffcdata **out_ffc)
2366 {
2367 62207 rpos_t cpos = rpos_t::None;
2368
2/2
✓ Branch 0 taken 65056 times.
✓ Branch 1 taken 127263 times.
62207 if(out_rpos)
2369 {
2370 127263 int32_t id = MAPCOMBO2(layer-1,x,y);
2371
2/2
✓ Branch 0 taken 29204 times.
✓ Branch 1 taken 98059 times.
127263 if(id > 0)
2372 {
2373 98059 newcombo const& cmb = combobuf[id];
2374
4/4
✓ Branch 0 taken 32974 times.
✓ Branch 1 taken 65085 times.
✓ Branch 2 taken 32528 times.
✓ Branch 3 taken 32557 times.
98059 cpos = (switchhook ? isSwitchHookable(cmb) : isHSGrabbable(cmb)) ? COMBOPOS_REGION(x,y) : rpos_t::None;
2375 33003 }
2376 62207 }
2377
2378 127263 ffcdata* ffc = nullptr;
2379
4/4
✓ Branch 0 taken 28531 times.
✓ Branch 1 taken 98732 times.
✓ Branch 2 taken 24996 times.
✓ Branch 3 taken 3535 times.
127263 if (out_ffc && !get_qr(qr_OLD_FFC_FUNCTIONALITY))
2380 {
2381 10645 for_some_ffcs([&](const ffc_handle_t& ffc_handle) {
2382
2/2
✓ Branch 0 taken 6995 times.
✓ Branch 1 taken 115 times.
7110 if (ffcIsAt(ffc_handle, x, y))
2383 {
2384 115 auto& cmb = ffc_handle.combo();
2385
4/4
✓ Branch 0 taken 42 times.
✓ Branch 1 taken 73 times.
✓ Branch 2 taken 37 times.
✓ Branch 3 taken 36 times.
115 if (switchhook ? isSwitchHookable(cmb) : isHSGrabbable(cmb))
2386 {
2387 79 ffc = ffc_handle.ffc;
2388 79 return false;
2389 }
2390 36 }
2391 7031 return true;
2392 7038 });
2393 3535 }
2394
2395
4/4
✓ Branch 0 taken 62207 times.
✓ Branch 1 taken 65056 times.
✓ Branch 2 taken 446 times.
✓ Branch 3 taken 61761 times.
127263 if (out_rpos && cpos != rpos_t::None) *out_rpos = cpos;
2396
4/4
✓ Branch 0 taken 28531 times.
✓ Branch 1 taken 98732 times.
✓ Branch 2 taken 7 times.
✓ Branch 3 taken 28524 times.
127263 if (out_ffc && ffc) *out_ffc = ffc;
2397
2/2
✓ Branch 0 taken 65502 times.
✓ Branch 1 taken 61761 times.
127263 return (cpos != rpos_t::None || ffc);
2398 }
2399
2400 5199 bool ishookshottable(int32_t bx, int32_t by)
2401 {
2402
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5199 times.
5199 if(!_walkflag(bx,by,1))
2403 return true;
2404
2405
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 5191 times.
5199 if (collide_object(bx, by, 1, 1))
2406 8 return false;
2407
2408 5191 bool ret = true;
2409
2/2
✓ Branch 0 taken 15573 times.
✓ Branch 1 taken 1904 times.
17477 for(int32_t i=2; i>=0; i--)
2410 {
2411 15573 int32_t c = MAPCOMBO2(i-1,bx,by);
2412 15573 int32_t t = combobuf[c].type;
2413
2414
6/6
✓ Branch 0 taken 5191 times.
✓ Branch 1 taken 10382 times.
✓ Branch 2 taken 3857 times.
✓ Branch 3 taken 1334 times.
✓ Branch 4 taken 1904 times.
✓ Branch 5 taken 1953 times.
15573 if(i == 0 && (t == cHOOKSHOTONLY || t == cLADDERHOOKSHOT)) return true;
2415
2416
3/4
✓ Branch 0 taken 11333 times.
✓ Branch 1 taken 953 times.
✓ Branch 2 taken 953 times.
✗ Branch 3 not taken.
13239 bool dried = (iswater_type(t) && DRIEDLAKE);
2417
2418 12286 int32_t b=1;
2419
2420
2/2
✓ Branch 0 taken 6112 times.
✓ Branch 1 taken 6174 times.
12286 if(bx&8) b<<=2;
2421
2422
2/2
✓ Branch 0 taken 3853 times.
✓ Branch 1 taken 8433 times.
12286 if(by&8) b<<=1;
2423
2424
7/8
✓ Branch 0 taken 2098 times.
✓ Branch 1 taken 10188 times.
✓ Branch 2 taken 2098 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1115 times.
✓ Branch 5 taken 983 times.
✓ Branch 6 taken 75 times.
✓ Branch 7 taken 908 times.
12286 if(combobuf[c].walk&b && !dried && !(combo_class_buf[t].ladder_pass && t!=cLADDERONLY) && t!=cHOOKSHOTONLY)
2425 908 ret = false;
2426 12286 }
2427
2428 1904 return ret;
2429 5199 }
2430
2431 11108 bool reveal_hidden_stairs(mapscr *s, int32_t screen, bool redraw)
2432 {
2433
4/4
✓ Branch 0 taken 10529 times.
✓ Branch 1 taken 579 times.
✓ Branch 2 taken 10529 times.
✓ Branch 3 taken 579 times.
11108 if((s->stairx || s->stairy) && s->secretcombo[sSTAIRS])
2434 {
2435 579 int pos = COMBOPOS(s->stairx,s->stairy);
2436 579 s->data[pos] = s->secretcombo[sSTAIRS];
2437 579 s->cset[pos] = s->secretcset[sSTAIRS];
2438 579 s->sflag[pos] = s->secretflag[sSTAIRS];
2439
2440
2/2
✓ Branch 0 taken 256 times.
✓ Branch 1 taken 323 times.
579 if (redraw)
2441 {
2442 768 auto [x, y] = translate_screen_coordinates_to_world(screen, s->stairx, s->stairy);
2443 768 putcombo(scrollbuf,x,y,s->data[pos],s->cset[pos]);
2444 256 }
2445
2446 579 return true;
2447 }
2448
2449 10529 return false;
2450 11108 }
2451
2452 52906 screen_handles_t create_screen_handles_one(mapscr* base_scr)
2453 {
2454 DCHECK(base_scr->is_valid());
2455
2456 52906 screen_handles_t screen_handles{};
2457 52906 screen_handles[0] = {base_scr, base_scr, base_scr->screen, 0};
2458 52906 return screen_handles;
2459 }
2460
2461 58566906 screen_handles_t create_screen_handles(mapscr* base_scr)
2462 {
2463 DCHECK(get_scr(base_scr->screen) == base_scr);
2464 DCHECK(base_scr->is_valid());
2465
2466 58566906 int screen = base_scr->screen;
2467 screen_handles_t screen_handles;
2468 58566906 screen_handles[0] = {base_scr, base_scr, screen, 0};
2469
2/2
✓ Branch 0 taken 351401436 times.
✓ Branch 1 taken 58566906 times.
409968342 for (int i = 1; i <= 6; i++)
2470 351401436 screen_handles[i] = {base_scr, get_scr_layer_valid(screen, i), screen, i};
2471 58566906 return screen_handles;
2472 }
2473
2474 113471 bool remove_screenstatecombos2(const screen_handles_t& screen_handles, bool do_layers, int32_t what1, int32_t what2)
2475 {
2476 113471 mapscr* scr = screen_handles[0].scr;
2477 113471 bool didit=false;
2478
2479
2/2
✓ Branch 0 taken 113471 times.
✓ Branch 1 taken 19970896 times.
20084367 for(int32_t i=0; i<176; i++)
2480 {
2481 19970896 newcombo const& cmb = combobuf[scr->data[i]];
2482
2/2
✓ Branch 0 taken 326 times.
✓ Branch 1 taken 19970570 times.
19970896 if(cmb.usrflags&cflag16) continue; //custom state instead of normal state
2483
4/4
✓ Branch 0 taken 19968994 times.
✓ Branch 1 taken 1576 times.
✓ Branch 2 taken 1134 times.
✓ Branch 3 taken 19967860 times.
19970570 if((cmb.type == what1) || (cmb.type== what2))
2484 {
2485 2710 scr->data[i]++;
2486 2710 didit=true;
2487 2710 }
2488 19970570 }
2489
2490
2/2
✓ Branch 0 taken 92 times.
✓ Branch 1 taken 113379 times.
113471 if (do_layers)
2491 {
2492
2/2
✓ Branch 0 taken 680274 times.
✓ Branch 1 taken 113379 times.
793653 for(int32_t j=1; j<=6; j++)
2493 {
2494 680274 mapscr* layer_scr = screen_handles[j].scr;
2495
2/2
✓ Branch 0 taken 195881 times.
✓ Branch 1 taken 484393 times.
680274 if (!layer_scr) continue;
2496
2497
2/2
✓ Branch 0 taken 34475056 times.
✓ Branch 1 taken 195881 times.
34670937 for(int32_t i=0; i<176; i++)
2498 {
2499 34475056 newcombo const& cmb = combobuf[layer_scr->data[i]];
2500
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 34475056 times.
34475056 if(cmb.usrflags&cflag16) continue; //custom state instead of normal state
2501
4/4
✓ Branch 0 taken 34474741 times.
✓ Branch 1 taken 315 times.
✓ Branch 2 taken 319 times.
✓ Branch 3 taken 34474422 times.
34475056 if((cmb.type== what1) || (cmb.type== what2))
2502 {
2503 634 layer_scr->data[i]++;
2504 634 didit=true;
2505 634 }
2506 34475056 }
2507 195881 }
2508 113379 }
2509
2510 // 'do_layers' also means that this is called on an active temp screen, so update its ffcs.
2511
3/4
✓ Branch 0 taken 27675 times.
✓ Branch 1 taken 85796 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 27675 times.
113471 if (!get_qr(qr_OLD_FFC_FUNCTIONALITY) && do_layers)
2512 {
2513 27675 word c = scr->numFFC();
2514
2/2
✓ Branch 0 taken 80883 times.
✓ Branch 1 taken 27675 times.
108558 for(word i=0; i<c; i++)
2515 {
2516 80883 ffcdata* ffc = &scr->ffcs[i];
2517 80883 newcombo const& cmb = combobuf[ffc->data];
2518
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 80883 times.
80883 if(cmb.usrflags&cflag16) continue; //custom state instead of normal state
2519
2/4
✓ Branch 0 taken 80883 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 80883 times.
80883 if((cmb.type== what1) || (cmb.type== what2))
2520 {
2521 zc_ffc_modify(*ffc, 1);
2522 didit=true;
2523 }
2524 80883 }
2525 27675 }
2526
2527 113471 return didit;
2528 }
2529
2530 14 bool remove_xstatecombos(const screen_handles_t& screen_handles, byte xflag, bool triggers)
2531 {
2532 14 int screen = screen_handles[0].scr->screen;
2533
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14 times.
14 int mi = mapind(cur_map, screen >= 0x80 ? home_screen : screen);
2534 14 return remove_xstatecombos_mi(screen_handles, mi, xflag, triggers);
2535 }
2536 488377550 bool remove_xstatecombos_mi(const screen_handles_t& screen_handles, int32_t mi, byte xflag, bool triggers)
2537 {
2538 488377550 bool didit=false;
2539
2/2
✓ Branch 0 taken 488336589 times.
✓ Branch 1 taken 40961 times.
488377550 if(!getxmapflag_mi(mi, 1<<xflag)) return false;
2540
2541 40961 mapscr* s = screen_handles[0].scr;
2542 40961 int screen = s->screen;
2543 40961 bool is_active_screen = is_in_current_region(s);
2544
2545 34122305 for_every_rpos_in_screen(screen_handles, [&](const rpos_handle_t& rpos_handle) {
2546
4/4
✓ Branch 0 taken 49456 times.
✓ Branch 1 taken 34031888 times.
✓ Branch 2 taken 1891 times.
✓ Branch 3 taken 34079453 times.
34081344 if(triggers && force_ex_trigger_any(rpos_handle, xflag))
2547 1891 didit = true;
2548
2/2
✓ Branch 0 taken 64673 times.
✓ Branch 1 taken 34014780 times.
34079453 else switch (rpos_handle.ctype())
2549 {
2550 case cLOCKBLOCK: case cLOCKBLOCK2:
2551 case cBOSSLOCKBLOCK: case cBOSSLOCKBLOCK2:
2552 case cCHEST: case cCHEST2:
2553 case cLOCKEDCHEST: case cLOCKEDCHEST2:
2554 case cBOSSCHEST: case cBOSSCHEST2:
2555 {
2556 64673 auto& cmb = rpos_handle.combo();
2557
2/2
✓ Branch 0 taken 62059 times.
✓ Branch 1 taken 2614 times.
64673 if(!(cmb.usrflags&cflag16)) return; //custom state instead of normal state
2558
2/2
✓ Branch 0 taken 29 times.
✓ Branch 1 taken 62030 times.
62059 if(cmb.attribytes[5] == xflag)
2559 {
2560 29 rpos_handle.increment_data();
2561 29 didit=true;
2562 29 }
2563 62059 break;
2564 }
2565 }
2566 34081344 });
2567
2568
4/4
✓ Branch 0 taken 40889 times.
✓ Branch 1 taken 72 times.
✓ Branch 2 taken 31269 times.
✓ Branch 3 taken 9620 times.
40961 if (is_active_screen && !get_qr(qr_OLD_FFC_FUNCTIONALITY))
2569 {
2570 31269 word c = s->numFFC();
2571 31269 int screen_index_offset = get_region_screen_offset(screen);
2572
2/2
✓ Branch 0 taken 65746 times.
✓ Branch 1 taken 31269 times.
97015 for (uint8_t i = 0; i < c; i++)
2573 {
2574 65746 auto ffc_handle = *s->getFFCHandle(i, screen_index_offset);
2575 65746 auto& cmb = ffc_handle.combo();
2576
3/4
✗ Branch 0 not taken.
✓ Branch 1 taken 65746 times.
✓ Branch 2 taken 16 times.
✓ Branch 3 taken 65730 times.
65746 if(triggers && force_ex_trigger_any(ffc_handle, xflag))
2577 16 didit = true;
2578
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 65730 times.
65730 else switch(cmb.type)
2579 {
2580 case cLOCKBLOCK: case cLOCKBLOCK2:
2581 case cBOSSLOCKBLOCK: case cBOSSLOCKBLOCK2:
2582 case cCHEST: case cCHEST2:
2583 case cLOCKEDCHEST: case cLOCKEDCHEST2:
2584 case cBOSSCHEST: case cBOSSCHEST2:
2585 {
2586 if(!(cmb.usrflags&cflag16)) continue; //custom state instead of normal state
2587 if(cmb.attribytes[5] == xflag)
2588 {
2589 zc_ffc_modify(*ffc_handle.ffc, 1);
2590 didit=true;
2591 }
2592 break;
2593 }
2594 }
2595 65746 }
2596 31269 }
2597
2598 40961 return didit;
2599 488377550 }
2600
2601 15208669 void clear_xstatecombos(const screen_handles_t& screen_handles, bool triggers)
2602 {
2603 15208669 int screen = screen_handles[0].screen;
2604
2/2
✓ Branch 0 taken 387833 times.
✓ Branch 1 taken 14820836 times.
15208669 int mi = mapind(cur_map, screen >= 0x80 ? home_screen : screen);
2605 15208669 clear_xstatecombos_mi(screen_handles, mi, triggers);
2606 15208669 }
2607
2608 15261798 void clear_xstatecombos_mi(const screen_handles_t& screen_handles, int32_t mi, bool triggers)
2609 {
2610
2/2
✓ Branch 0 taken 488377536 times.
✓ Branch 1 taken 15261798 times.
503639334 for (int q = 0; q < 32; ++q)
2611 {
2612 488377536 remove_xstatecombos_mi(screen_handles, mi, q, triggers);
2613 488377536 }
2614 15261798 }
2615
2616 bool remove_xdoors(const screen_handles_t& screen_handles, uint dir, uint ind, bool triggers)
2617 {
2618 int screen = screen_handles[0].screen;
2619 int mi = mapind(cur_map, screen >= 0x80 ? home_screen : screen);
2620 return remove_xdoors_mi(screen_handles, mi, dir, ind, triggers);
2621 }
2622 488377536 bool remove_xdoors_mi(const screen_handles_t& screen_handles, int32_t mi, uint dir, uint ind, bool triggers)
2623 {
2624 488377536 bool didit=false;
2625
2/2
✓ Branch 0 taken 488376223 times.
✓ Branch 1 taken 1313 times.
488377536 if (!getxdoor_mi(mi, dir, ind)) return false;
2626
2627 1313 mapscr* scr = screen_handles[0].scr;
2628 1313 int screen = scr->screen;
2629 1313 bool is_active_screen = is_in_current_region(scr);
2630
2631 925665 for_every_rpos_in_screen(screen_handles, [&](const rpos_handle_t& rpos_handle) {
2632
3/4
✗ Branch 0 not taken.
✓ Branch 1 taken 924352 times.
✓ Branch 2 taken 11 times.
✓ Branch 3 taken 924341 times.
924352 if (triggers && force_ex_door_trigger_any(rpos_handle, dir, ind))
2633 11 didit = true;
2634 else; //future door combo types?
2635 924352 });
2636
2637
2/4
✓ Branch 0 taken 1313 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1313 times.
✗ Branch 3 not taken.
1313 if (!get_qr(qr_OLD_FFC_FUNCTIONALITY) && is_active_screen)
2638 {
2639 1313 word c = scr->numFFC();
2640 1313 int screen_index_offset = get_region_screen_offset(screen);
2641
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1313 times.
1313 for (uint8_t i = 0; i < c; i++)
2642 {
2643 auto ffc_handle = *scr->getFFCHandle(i, screen_index_offset);
2644 if (triggers && force_ex_door_trigger_any(ffc_handle, dir, ind))
2645 didit = true;
2646 else; //future door combo types?
2647 }
2648 1313 }
2649
2650 1313 return didit;
2651 488377536 }
2652
2653 15208669 void clear_xdoors(const screen_handles_t& screen_handles, bool triggers)
2654 {
2655 15208669 int screen = screen_handles[0].screen;
2656
2/2
✓ Branch 0 taken 387833 times.
✓ Branch 1 taken 14820836 times.
15208669 int mi = mapind(cur_map, screen >= 0x80 ? home_screen : screen);
2657 15208669 return clear_xdoors_mi(screen_handles, mi, triggers);
2658 }
2659
2660 15261798 void clear_xdoors_mi(const screen_handles_t& screen_handles, int32_t mi, bool triggers)
2661 {
2662
2/2
✓ Branch 0 taken 61047192 times.
✓ Branch 1 taken 15261798 times.
76308990 for (int dir = 0; dir < 4; ++dir)
2663
2/2
✓ Branch 0 taken 488377536 times.
✓ Branch 1 taken 61047192 times.
549424728 for (int q = 0; q < 8; ++q)
2664 549424728 remove_xdoors_mi(screen_handles, mi, dir, q, triggers);
2665 15261798 }
2666
2667 885 bool remove_lockblocks(const screen_handles_t& screen_handles)
2668 {
2669 885 return remove_screenstatecombos2(screen_handles, true, cLOCKBLOCK, cLOCKBLOCK2);
2670 }
2671
2672 139 bool remove_bosslockblocks(const screen_handles_t& screen_handles)
2673 {
2674 139 return remove_screenstatecombos2(screen_handles, true, cBOSSLOCKBLOCK, cBOSSLOCKBLOCK2);
2675 }
2676
2677 83659 bool remove_chests(const screen_handles_t& screen_handles)
2678 {
2679 83659 return remove_screenstatecombos2(screen_handles, true, cCHEST, cCHEST2);
2680 }
2681
2682 2484 bool remove_lockedchests(const screen_handles_t& screen_handles)
2683 {
2684 2484 return remove_screenstatecombos2(screen_handles, true, cLOCKEDCHEST, cLOCKEDCHEST2);
2685 }
2686
2687 26212 bool remove_bosschests(const screen_handles_t& screen_handles)
2688 {
2689 26212 return remove_screenstatecombos2(screen_handles, true, cBOSSCHEST, cBOSSCHEST2);
2690 }
2691
2692 1418795 void delete_fireball_shooter(const rpos_handle_t& rpos_handle)
2693 {
2694 1418795 int32_t ct=rpos_handle.ctype();
2695
2696
6/6
✓ Branch 0 taken 1418175 times.
✓ Branch 1 taken 620 times.
✓ Branch 2 taken 1417923 times.
✓ Branch 3 taken 252 times.
✓ Branch 4 taken 1417815 times.
✓ Branch 5 taken 108 times.
1418795 if(ct!=cL_STATUE && ct!=cR_STATUE && ct!=cC_STATUE)
2697 1417815 return;
2698
2699 2465 auto [cx, cy] = rpos_handle.xy();
2700
3/4
✓ Branch 0 taken 252 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 620 times.
✓ Branch 3 taken 108 times.
980 switch(ct)
2701 {
2702 case cL_STATUE:
2703 620 cx += 4;
2704 620 cy += 7;
2705 620 break;
2706
2707 case cR_STATUE:
2708 252 cx -= 8;
2709 252 cy -= 1;
2710 252 break;
2711
2712 case cC_STATUE:
2713 108 break;
2714 }
2715
2716
2/2
✓ Branch 0 taken 980 times.
✓ Branch 1 taken 1485 times.
2465 for(int32_t j=0; j<guys.Count(); j++)
2717 {
2718 // Finds the smallest enemy ID
2719
9/10
✓ Branch 0 taken 399 times.
✓ Branch 1 taken 1086 times.
✓ Branch 2 taken 399 times.
✓ Branch 3 taken 1086 times.
✓ Branch 4 taken 346 times.
✓ Branch 5 taken 53 times.
✓ Branch 6 taken 346 times.
✓ Branch 7 taken 53 times.
✓ Branch 8 taken 346 times.
✗ Branch 9 not taken.
2970 if((int32_t(guys.spr(j)->x)==cx)&&(int32_t(guys.spr(j)->y)==cy)&&(guysbuf[(guys.spr(j)->id)&0xFFF].flags & guy_fire))
2720 {
2721 346 guys.del(j);
2722 346 }
2723 1485 }
2724 1418795 }
2725
2726 45 static int32_t findtrigger(int32_t screen)
2727 {
2728 45 int32_t checkflag=0;
2729 45 int32_t ret = 0;
2730
2731 mapscr* screens[7];
2732
2/2
✓ Branch 0 taken 315 times.
✓ Branch 1 taken 45 times.
360 for (int32_t j = 0; j <= 6; j++)
2733 {
2734 315 screens[j] = get_scr_layer_valid(screen, j);
2735 315 }
2736
2737 45 bool sflag = false;
2738
2/2
✓ Branch 0 taken 7920 times.
✓ Branch 1 taken 45 times.
7965 for(word j=0; j<176; j++)
2739 {
2740
2/2
✓ Branch 0 taken 87648 times.
✓ Branch 1 taken 7920 times.
95568 for(int32_t layer = -1; layer < 6; ++layer)
2741 {
2742 87648 mapscr* scr = screens[layer+1];
2743
2/2
✓ Branch 0 taken 64416 times.
✓ Branch 1 taken 23232 times.
87648 if (!scr) continue;
2744
2745
2/2
✓ Branch 0 taken 32208 times.
✓ Branch 1 taken 32208 times.
64416 if(sflag)
2746 32208 checkflag = scr->sflag[j];
2747 else
2748 32208 checkflag = combobuf[scr->data[j]].flag;
2749 64416 sflag = !sflag;
2750
2/2
✓ Branch 0 taken 32208 times.
✓ Branch 1 taken 32208 times.
64416 if (sflag) --layer;
2751
2752
2/2
✓ Branch 0 taken 42 times.
✓ Branch 1 taken 64374 times.
64416 switch(checkflag)
2753 {
2754 case mfANYFIRE:
2755 case mfSTRONGFIRE:
2756 case mfMAGICFIRE:
2757 case mfDIVINEFIRE:
2758 case mfARROW:
2759 case mfSARROW:
2760 case mfGARROW:
2761 case mfSBOMB:
2762 case mfBOMB:
2763 case mfBRANG:
2764 case mfMBRANG:
2765 case mfFBRANG:
2766 case mfWANDMAGIC:
2767 case mfREFMAGIC:
2768 case mfREFFIREBALL:
2769 case mfSWORD:
2770 case mfWSWORD:
2771 case mfMSWORD:
2772 case mfXSWORD:
2773 case mfSWORDBEAM:
2774 case mfWSWORDBEAM:
2775 case mfMSWORDBEAM:
2776 case mfXSWORDBEAM:
2777 case mfHOOKSHOT:
2778 case mfWAND:
2779 case mfHAMMER:
2780 case mfSTRIKE:
2781 42 ret += 1;
2782 42 break;
2783 }
2784 64416 }
2785 7920 }
2786
2787 45 return ret;
2788 }
2789
2790 12340 static void log_trigger_secret_reason(TriggerSource source)
2791 {
2792
2/2
✓ Branch 0 taken 452 times.
✓ Branch 1 taken 11888 times.
12340 if (source == TriggerSource::Singular)
2793 {
2794 452 Z_eventlog("Restricted Screen Secrets triggered\n");
2795 452 }
2796 else
2797 {
2798 11888 const char* source_str = "";
2799
7/12
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✓ Branch 2 taken 7297 times.
✓ Branch 3 taken 897 times.
✓ Branch 4 taken 3114 times.
✓ Branch 5 taken 500 times.
✓ Branch 6 taken 1 times.
✓ Branch 7 taken 75 times.
✓ Branch 8 taken 4 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
11888 switch (source)
2800 {
2801 case TriggerSource::Singular: break;
2802 7297 case TriggerSource::Unspecified: source_str = "unspecified means"; break;
2803 897 case TriggerSource::EnemiesScreenFlag: source_str = "the 'Enemies->Secret' screen flag"; break;
2804 3114 case TriggerSource::SecretsScreenState: source_str = "the 'Secrets' screen state"; break;
2805 500 case TriggerSource::Script: source_str = "a script"; break;
2806 1 case TriggerSource::ItemsSecret: source_str = "Items->Secrets"; break;
2807 75 case TriggerSource::GenericCombo: source_str = "Generic Combo"; break;
2808 4 case TriggerSource::LightTrigger: source_str = "Light Triggers"; break;
2809 case TriggerSource::SCC: source_str = "SCC"; break;
2810 case TriggerSource::CheatTemp: source_str = "Cheat (Temp)"; break;
2811 case TriggerSource::CheatPerm: source_str = "Cheat (Perm)"; break;
2812 }
2813 11888 Z_eventlog("Screen Secrets triggered by %s\n", source_str);
2814 }
2815 12340 }
2816
2817 // single:
2818 // >-1 : the singular triggering combo
2819 // -1: triggered by some other cause
2820 12132 void trigger_secrets_for_screen(TriggerSource source, mapscr* scr, bool high16only, int32_t single)
2821 {
2822 12132 log_trigger_secret_reason(source);
2823
2/2
✓ Branch 0 taken 452 times.
✓ Branch 1 taken 11680 times.
12132 if (single < 0)
2824 11680 get_screen_state(scr->screen).triggered_secrets = true;
2825
2826 12132 bool do_replay_comment = true;
2827 12132 bool from_active_screen = true;
2828 12132 trigger_secrets_for_screen_internal(create_screen_handles(scr), from_active_screen, high16only, single, do_replay_comment);
2829
2830 // Respect secret state carryovers for active screens.
2831
2/2
✓ Branch 0 taken 452 times.
✓ Branch 1 taken 11680 times.
12132 if (single >= 0) return;
2832
2/2
✓ Branch 0 taken 25 times.
✓ Branch 1 taken 11655 times.
11680 if(scr->nocarry&mSECRET) return;
2833 11655 int cmap = scr->map;
2834 11655 int cscr = scr->screen;
2835 11655 int nmap=TheMaps[((cmap)*MAPSCRS)+cscr].nextmap;
2836 11655 int nscr=TheMaps[((cmap)*MAPSCRS)+cscr].nextscr;
2837
2838 11655 std::vector<int32_t> done;
2839
2/2
✓ Branch 0 taken 11450 times.
✓ Branch 1 taken 205 times.
11655 bool looped = (nmap==cmap+1 && nscr==cscr);
2840
2841
6/6
✓ Branch 0 taken 586 times.
✓ Branch 1 taken 11569 times.
✓ Branch 2 taken 86 times.
✓ Branch 3 taken 500 times.
✓ Branch 4 taken 500 times.
✓ Branch 5 taken 11655 times.
12155 while((nmap!=0) && !looped && !(nscr>=128))
2842 {
2843
7/8
✓ Branch 0 taken 388 times.
✓ Branch 1 taken 112 times.
✓ Branch 2 taken 93 times.
✓ Branch 3 taken 295 times.
✓ Branch 4 taken 93 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 4 times.
✓ Branch 7 taken 89 times.
500 if (nmap - 1 == cur_map && is_in_current_region(nscr) && !get_screen_state(nscr).triggered_secrets)
2844 {
2845
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 log_trigger_secret_reason(TriggerSource::SecretsScreenState);
2846
3/6
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 4 times.
✗ Branch 5 not taken.
4 trigger_secrets_for_screen_internal(create_screen_handles(get_scr(nscr)), from_active_screen, high16only, single, do_replay_comment);
2847
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 get_screen_state(nscr).triggered_secrets = true;
2848 4 }
2849
2850 500 cmap=nmap;
2851 500 cscr=nscr;
2852 500 nmap=TheMaps[((cmap-1)*MAPSCRS)+cscr].nextmap;
2853 500 nscr=TheMaps[((cmap-1)*MAPSCRS)+cscr].nextscr;
2854
2855
2/2
✓ Branch 0 taken 443 times.
✓ Branch 1 taken 500 times.
943 for(auto it = done.begin(); it != done.end(); it++)
2856 {
2857
2/2
✓ Branch 0 taken 357 times.
✓ Branch 1 taken 86 times.
443 if(*it == ((nmap-1)<<7)+nscr)
2858 86 looped = true;
2859 443 }
2860
2861
1/2
✓ Branch 0 taken 500 times.
✗ Branch 1 not taken.
500 done.push_back(((nmap-1)<<7)+nscr);
2862 }
2863 12132 }
2864
2865 2550 void trigger_secrets_for_screen(TriggerSource source, int32_t screen, bool high16only, int32_t single)
2866 {
2867 2550 trigger_secrets_for_screen(source, get_scr(screen), high16only, single);
2868 2550 }
2869
2870 19223 void trigger_secrets_for_screen_internal(const screen_handles_t& screen_handles, bool from_active_screen, bool high16only, int32_t single, bool do_replay_comment)
2871 {
2872 19223 mapscr* scr = screen_handles[0].scr;
2873 19223 int screen = scr->screen;
2874
2875 // TODO(replays): No real reason for "do_replay_comment" to exist - I just did not want to update many replays when fixing
2876 // slopes in sideview mode (which required loading nearby screens in loadscr).
2877 // TODO(replays): This should just use `screen`.
2878
3/4
✓ Branch 0 taken 19223 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 539 times.
✓ Branch 3 taken 18684 times.
19223 if (replay_is_active() && do_replay_comment)
2879
4/6
✓ Branch 0 taken 12136 times.
✓ Branch 1 taken 6548 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 12136 times.
✓ Branch 4 taken 18684 times.
✗ Branch 5 not taken.
18684 replay_step_comment(fmt::format("trigger secrets scr={}", from_active_screen && scr != special_warp_return_scr ? screen : cur_screen));
2880
2881
2/2
✓ Branch 0 taken 7087 times.
✓ Branch 1 taken 12136 times.
19223 if (from_active_screen)
2882 {
2883 6099822 for_every_combo_in_screen(screen_handles, [&](const auto& handle) {
2884
2/4
✓ Branch 0 taken 6085024 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2662 times.
✗ Branch 3 not taken.
6407603 trig_each_combo_trigger(handle, [&](combo_trigger const& trig){
2885 319917 return trig.trigger_flags.get(TRIGFLAG_SECRETSTR);
2886 }, ctrigSECRETS);
2887 6087686 });
2888 12136 }
2889
2890 19223 int32_t ft=0; //Flag trigger?
2891 19223 int32_t msflag=0; // Misc. secret flag
2892
2893
2/2
✓ Branch 0 taken 3383248 times.
✓ Branch 1 taken 19223 times.
3402471 for(int32_t i=0; i<176; i++) //Do the 'trigger flags' (non 16-31)
2894 {
2895
4/4
✓ Branch 0 taken 79552 times.
✓ Branch 1 taken 3303696 times.
✓ Branch 2 taken 452 times.
✓ Branch 3 taken 79100 times.
3383248 if(single>=0 && i!=single) continue; //If it's got a singular flag and i isn't where the flag is
2896
2897 // Remember the misc. secret flag; if triggered, use this instead
2898
4/4
✓ Branch 0 taken 153551 times.
✓ Branch 1 taken 3150597 times.
✓ Branch 2 taken 87558 times.
✓ Branch 3 taken 65993 times.
3304148 if(scr->sflag[i]>=mfSECRETS01 && scr->sflag[i]<=mfSECRETS16)
2899 65993 msflag=sSECRET01+(scr->sflag[i]-mfSECRETS01);
2900
4/4
✓ Branch 0 taken 47862 times.
✓ Branch 1 taken 3190293 times.
✓ Branch 2 taken 47336 times.
✓ Branch 3 taken 526 times.
3238155 else if(combobuf[scr->data[i]].flag>=mfSECRETS01 && combobuf[scr->data[i]].flag<=mfSECRETS16)
2901 526 msflag=sSECRET01+(combobuf[scr->data[i]].flag-mfSECRETS01);
2902 else
2903 3237629 msflag=0;
2904
2905
4/4
✓ Branch 0 taken 922853 times.
✓ Branch 1 taken 2381295 times.
✓ Branch 2 taken 85 times.
✓ Branch 3 taken 922768 times.
3304148 if(!high16only || single>=0)
2906 {
2907 2381380 int32_t newflag = -1;
2908
2909
2/2
✓ Branch 0 taken 4762760 times.
✓ Branch 1 taken 2381380 times.
7144140 for(int32_t iter=0; iter<2; ++iter)
2910 {
2911 4762760 int32_t checkflag=combobuf[scr->data[i]].flag; //Inherent
2912
2913
2/2
✓ Branch 0 taken 2381380 times.
✓ Branch 1 taken 2381380 times.
4762760 if(iter==1) checkflag=scr->sflag[i]; //Placed
2914
2915 4762760 ft = combo_trigger_flag_to_secret_combo_index(checkflag);
2916
2/2
✓ Branch 0 taken 4750287 times.
✓ Branch 1 taken 12473 times.
4762760 if (ft != -1) //Change the combos for the secret
2917 {
2918 // Use misc. secret flag instead if one is present
2919
2/2
✓ Branch 0 taken 12441 times.
✓ Branch 1 taken 32 times.
12473 if(msflag!=0)
2920 32 ft=msflag;
2921
2922 12473 rpos_handle_t rpos_handle;
2923
2/2
✓ Branch 0 taken 6541 times.
✓ Branch 1 taken 5932 times.
12473 if (from_active_screen)
2924 {
2925 5932 rpos_handle = get_rpos_handle_for_scr(scr, 0, i);
2926 5932 screen_combo_modify_preroutine(rpos_handle);
2927 5932 }
2928
2929
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 12473 times.
12473 if(ft==sSECNEXT)
2930 {
2931 scr->data[i]++;
2932 }
2933 else
2934 {
2935 12473 scr->data[i] = scr->secretcombo[ft];
2936 12473 scr->cset[i] = scr->secretcset[ft];
2937 }
2938 12473 newflag = scr->secretflag[ft];
2939
2940
2/2
✓ Branch 0 taken 6541 times.
✓ Branch 1 taken 5932 times.
12473 if (from_active_screen)
2941 5932 screen_combo_modify_postroutine(rpos_handle);
2942 12473 }
2943 4762760 }
2944
2945
2/2
✓ Branch 0 taken 2368913 times.
✓ Branch 1 taken 12467 times.
2381380 if(newflag >-1) scr->sflag[i] = newflag; //Tiered secret
2946
2947
2/2
✓ Branch 0 taken 14288280 times.
✓ Branch 1 taken 2381380 times.
16669660 for(int32_t j=1; j<=6; j++) //Layers
2948 {
2949 14288280 mapscr* layer_scr = screen_handles[j].scr;
2950
2/2
✓ Branch 0 taken 4300978 times.
✓ Branch 1 taken 9987302 times.
14288280 if (!layer_scr) continue;
2951
2952
3/4
✓ Branch 0 taken 770 times.
✓ Branch 1 taken 4300208 times.
✓ Branch 2 taken 770 times.
✗ Branch 3 not taken.
4300978 if(single>=0 && i!=single) continue; //If it's got a singular flag and i isn't where the flag is
2953
2954 4300978 int32_t newflag2 = -1;
2955
2956 // Remember the misc. secret flag; if triggered, use this instead
2957
4/4
✓ Branch 0 taken 18068 times.
✓ Branch 1 taken 4282910 times.
✓ Branch 2 taken 6284 times.
✓ Branch 3 taken 11784 times.
4300978 if(layer_scr->sflag[i]>=mfSECRETS01 && layer_scr->sflag[i]<=mfSECRETS16)
2958 11784 msflag=sSECRET01+(layer_scr->sflag[i]-mfSECRETS01);
2959
4/4
✓ Branch 0 taken 132026 times.
✓ Branch 1 taken 4157168 times.
✓ Branch 2 taken 130774 times.
✓ Branch 3 taken 1252 times.
4289194 else if(combobuf[layer_scr->data[i]].flag>=mfSECRETS01 && combobuf[layer_scr->data[i]].flag<=mfSECRETS16)
2960 1252 msflag=sSECRET01+(combobuf[layer_scr->data[i]].flag-mfSECRETS01);
2961 else
2962 4287942 msflag=0;
2963
2964
2/2
✓ Branch 0 taken 8601956 times.
✓ Branch 1 taken 4300978 times.
12902934 for(int32_t iter=0; iter<2; ++iter)
2965 {
2966 8601956 int32_t checkflag=combobuf[layer_scr->data[i]].flag; //Inherent
2967
2/2
✓ Branch 0 taken 4300978 times.
✓ Branch 1 taken 4300978 times.
8601956 if(iter==1) checkflag=layer_scr->sflag[i]; //Placed
2968
2969 8601956 ft = combo_trigger_flag_to_secret_combo_index(checkflag);
2970
2/2
✓ Branch 0 taken 8600177 times.
✓ Branch 1 taken 1779 times.
8601956 if (ft != -1) //Change the combos for the secret
2971 {
2972 // Use misc. secret flag instead if one is present
2973
2/2
✓ Branch 0 taken 1777 times.
✓ Branch 1 taken 2 times.
1779 if(msflag!=0)
2974 2 ft=msflag;
2975
2976
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1779 times.
1779 if(ft==sSECNEXT)
2977 {
2978 layer_scr->data[i]++;
2979 }
2980 else
2981 {
2982 1779 layer_scr->data[i] = layer_scr->secretcombo[ft];
2983 1779 layer_scr->cset[i] = layer_scr->secretcset[ft];
2984 }
2985 1779 newflag2 = layer_scr->secretflag[ft];
2986 1779 int32_t c=layer_scr->data[i];
2987 1779 int32_t cs=layer_scr->cset[i];
2988
2989
3/4
✓ Branch 0 taken 908 times.
✓ Branch 1 taken 871 times.
✓ Branch 2 taken 908 times.
✗ Branch 3 not taken.
1779 if (from_active_screen && combobuf[c].type==cSPINTILE1) //Surely this means we can have spin tiles on layers 3+? Isn't that bad? ~Joe123
2990 {
2991 auto [offx, offy] = translate_screen_coordinates_to_world(screen, COMBOX(i), COMBOY(i));
2992 addenemy(screen,offx,offy,(cs<<12)+eSPINTILE1,combobuf[c].o_tile+zc_max(1,combobuf[c].frames));
2993 }
2994 1779 }
2995 8601956 }
2996
2997
2/2
✓ Branch 0 taken 1766 times.
✓ Branch 1 taken 4299212 times.
4300978 if(newflag2 >-1) layer_scr->sflag[i] = newflag2; //Tiered secret
2998 4300978 }
2999 2381380 }
3000 3304148 }
3001
3002 19223 word c = scr->numFFC();
3003
2/2
✓ Branch 0 taken 508334 times.
✓ Branch 1 taken 19223 times.
527557 for(word i=0; i<c; i++) //FFC 'trigger flags'
3004 {
3005
3/4
✓ Branch 0 taken 494280 times.
✓ Branch 1 taken 14054 times.
✓ Branch 2 taken 14054 times.
✗ Branch 3 not taken.
508334 if(single>=0) if(i+176!=single) continue;
3006
3007
3/4
✓ Branch 0 taken 166649 times.
✓ Branch 1 taken 327631 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 166649 times.
494280 if((!high16only)||(single>=0))
3008 {
3009 //for (int32_t iter=0; iter<1; ++iter) // Only one kind of FFC flag now.
3010 {
3011 327631 int32_t checkflag=combobuf[scr->ffcs[i].data].flag; //Inherent
3012 //No placed flags yet
3013
3014 327631 ft = combo_trigger_flag_to_secret_combo_index(checkflag);
3015
2/2
✓ Branch 0 taken 327600 times.
✓ Branch 1 taken 31 times.
327631 if (ft != -1) //Change the ffc's combo
3016 {
3017
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 31 times.
31 if(ft==sSECNEXT)
3018 {
3019 zc_ffc_modify(scr->ffcs[i], 1);
3020 }
3021 else
3022 {
3023 31 zc_ffc_set(scr->ffcs[i], scr->secretcombo[ft]);
3024 31 scr->ffcs[i].cset = scr->secretcset[ft];
3025 }
3026 31 }
3027 }
3028 327631 }
3029 494280 }
3030
3031
2/2
✓ Branch 0 taken 16725 times.
✓ Branch 1 taken 2498 times.
19223 if(checktrigger) //Hit all triggers->16-31
3032 {
3033 2498 checktrigger=false;
3034
3035
2/2
✓ Branch 0 taken 2474 times.
✓ Branch 1 taken 24 times.
2498 if(scr->flags6&fTRIGGERF1631)
3036 {
3037 24 int32_t tr = findtrigger(screen); //Normal flags
3038
3039
2/2
✓ Branch 0 taken 14 times.
✓ Branch 1 taken 10 times.
24 if(tr)
3040 {
3041 14 Z_eventlog("Hit All Triggers->16-31 not fulfilled (%d trigger flag%s remain).\n", tr, tr>1?"s":"");
3042 14 goto endhe;
3043 }
3044 10 }
3045 2484 }
3046
3047
2/2
✓ Branch 0 taken 3380784 times.
✓ Branch 1 taken 19209 times.
3399993 for(int32_t i=0; i<176; i++) // Do the 16-31 secrets
3048 {
3049 //If it's an enemies->secret screen, only do the high 16 if told to
3050 //That way you can have secret and burn/bomb entrance separately
3051 3380784 bool old_enem_secret = get_qr(qr_ENEMIES_SECRET_ONLY_16_31);
3052
6/6
✓ Branch 0 taken 2780624 times.
✓ Branch 1 taken 600160 times.
✓ Branch 2 taken 85184 times.
✓ Branch 3 taken 3295600 times.
✓ Branch 4 taken 19536 times.
✓ Branch 5 taken 65648 times.
3380784 if(((!(old_enem_secret && (scr->flags2&fCLEARSECRET)) /*Enemies->Secret*/ && single < 0) || high16only || scr->flags4&fENEMYSCRTPERM))
3053 {
3054 3315136 int32_t newflag = -1;
3055
3056
2/2
✓ Branch 0 taken 6630272 times.
✓ Branch 1 taken 3315136 times.
9945408 for(int32_t iter=0; iter<2; ++iter)
3057 {
3058 6630272 int32_t checkflag=combobuf[scr->data[i]].flag; //Inherent
3059
3060
2/2
✓ Branch 0 taken 3315136 times.
✓ Branch 1 taken 3315136 times.
6630272 if(iter==1) checkflag=scr->sflag[i]; //Placed
3061
3062
4/4
✓ Branch 0 taken 200805 times.
✓ Branch 1 taken 6429467 times.
✓ Branch 2 taken 133230 times.
✓ Branch 3 taken 67575 times.
6630272 if((checkflag > 15)&&(checkflag < 32)) //If we've got a 16->32 flag change the combo
3063 {
3064 67575 rpos_handle_t rpos_handle;
3065
2/2
✓ Branch 0 taken 10367 times.
✓ Branch 1 taken 57208 times.
67575 if (from_active_screen)
3066 {
3067 57208 rpos_handle = get_rpos_handle_for_scr(scr, 0, i);
3068 57208 screen_combo_modify_preroutine(rpos_handle);
3069 57208 }
3070
3071 67575 scr->data[i] = scr->secretcombo[checkflag-16+4];
3072 67575 scr->cset[i] = scr->secretcset[checkflag-16+4];
3073 67575 newflag = scr->secretflag[checkflag-16+4];
3074
3075
2/2
✓ Branch 0 taken 10367 times.
✓ Branch 1 taken 57208 times.
67575 if (from_active_screen)
3076 57208 screen_combo_modify_postroutine(rpos_handle);
3077 67575 }
3078 6630272 }
3079
3080
2/2
✓ Branch 0 taken 3247589 times.
✓ Branch 1 taken 67547 times.
3315136 if(newflag >-1) scr->sflag[i] = newflag; //Tiered flag
3081
3082
2/2
✓ Branch 0 taken 19890816 times.
✓ Branch 1 taken 3315136 times.
23205952 for(int32_t j=1; j<=6; j++) //Layers
3083 {
3084 19890816 mapscr* layer_scr = screen_handles[j].scr;
3085
2/2
✓ Branch 0 taken 5992096 times.
✓ Branch 1 taken 13898720 times.
19890816 if (!layer_scr) continue;
3086
3087 5992096 int32_t newflag2 = -1;
3088
3089
2/2
✓ Branch 0 taken 11984192 times.
✓ Branch 1 taken 5992096 times.
17976288 for(int32_t iter=0; iter<2; ++iter)
3090 {
3091 11984192 int32_t checkflag=combobuf[layer_scr->data[i]].flag; //Inherent
3092
3093
2/2
✓ Branch 0 taken 5992096 times.
✓ Branch 1 taken 5992096 times.
11984192 if(iter==1) checkflag=layer_scr->sflag[i]; //Placed
3094
3095
4/4
✓ Branch 0 taken 159433 times.
✓ Branch 1 taken 11824759 times.
✓ Branch 2 taken 136546 times.
✓ Branch 3 taken 22887 times.
11984192 if((checkflag > 15)&&(checkflag < 32)) //If we've got a 16->32 flag change the combo
3096 {
3097 22887 layer_scr->data[i] = layer_scr->secretcombo[checkflag-16+4];
3098 22887 layer_scr->cset[i] = layer_scr->secretcset[checkflag-16+4];
3099 22887 newflag2 = layer_scr->secretflag[checkflag-16+4];
3100 22887 }
3101 11984192 }
3102
3103
2/2
✓ Branch 0 taken 5969209 times.
✓ Branch 1 taken 22887 times.
5992096 if(newflag2 >-1) layer_scr->sflag[i] = newflag2; //Tiered flag
3104 5992096 }
3105 3315136 }
3106 3380784 }
3107
3108
2/2
✓ Branch 0 taken 508074 times.
✓ Branch 1 taken 19209 times.
527283 for(word i=0; i<c; i++) // FFCs
3109 {
3110
6/6
✓ Branch 0 taken 468053 times.
✓ Branch 1 taken 40021 times.
✓ Branch 2 taken 15497 times.
✓ Branch 3 taken 492577 times.
✓ Branch 4 taken 3657 times.
✓ Branch 5 taken 11840 times.
508074 if((!(scr->flags2&fCLEARSECRET) /*Enemies->Secret*/ && single < 0) || high16only || scr->flags4&fENEMYSCRTPERM)
3111 {
3112 496234 int32_t checkflag=combobuf[scr->ffcs[i].data].flag; //Inherent
3113
3114 //No placed flags yet
3115
4/4
✓ Branch 0 taken 93 times.
✓ Branch 1 taken 496141 times.
✓ Branch 2 taken 81 times.
✓ Branch 3 taken 12 times.
496234 if((checkflag > 15)&&(checkflag < 32)) //If we find a flag, change the combo
3116 {
3117
2/2
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 3 times.
12 if (from_active_screen)
3118 9 zc_ffc_set(scr->ffcs[i], scr->secretcombo[checkflag - 16 + 4]);
3119 else
3120 3 scr->ffcs[i].data = scr->secretcombo[checkflag - 16 + 4];
3121 12 scr->ffcs[i].cset = scr->secretcset[checkflag-16+4];
3122 12 }
3123 496234 }
3124 527283 }
3125
3126 endhe:
3127
3128
1/2
✓ Branch 0 taken 19223 times.
✗ Branch 1 not taken.
19223 if (scr->flags4&fDISABLETIME) //Finish timed warp if 'Secrets Disable Timed Warp'
3129 {
3130 if (from_active_screen)
3131 activated_timed_warp = true;
3132 scr->timedwarptics = 0;
3133 }
3134 19223 }
3135
3136 // x,y are world coordinates.
3137 // Returns true if there is a flag (either combo, screen, or ffc) at (x, y).
3138 // Out parameters will be set if the flag is Trigger->Self, which modifies how secrets will be triggered.
3139 13982906 static bool has_flag_trigger(int32_t x, int32_t y, int32_t flag, rpos_t& out_rpos, bool& out_single16)
3140 {
3141
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 13982906 times.
13982906 if (!is_in_world_bounds(x, y)) return false;
3142
3143 13982906 bool found_cflag = false;
3144 13982906 bool found_nflag = false;
3145 13982906 bool single16 = false;
3146 13982906 rpos_t rpos = rpos_t::None;
3147
3148
2/2
✓ Branch 0 taken 13980804 times.
✓ Branch 1 taken 97868060 times.
111848864 for (int32_t layer = -1; layer < 6; layer++)
3149 {
3150
2/2
✓ Branch 0 taken 97865958 times.
✓ Branch 1 taken 2102 times.
97868060 if (MAPFLAG2(layer, x, y) == flag)
3151 {
3152 2102 found_nflag = true;
3153 2102 break;
3154 }
3155 97865958 }
3156
3157
2/2
✓ Branch 0 taken 13982517 times.
✓ Branch 1 taken 97878647 times.
111861164 for (int32_t layer = -1; layer < 6; layer++)
3158 {
3159
2/2
✓ Branch 0 taken 97878258 times.
✓ Branch 1 taken 389 times.
97878647 if (MAPCOMBOFLAG2(layer, x, y) == flag)
3160 {
3161 389 found_cflag = true;
3162 389 break;
3163 }
3164 97878258 }
3165
3166
2/2
✓ Branch 0 taken 97880342 times.
✓ Branch 1 taken 13982906 times.
111863248 for (int32_t i=-1; i<6; i++) // Look for Trigger->Self on all layers
3167 {
3168
2/2
✓ Branch 0 taken 97865628 times.
✓ Branch 1 taken 14714 times.
97880342 if (found_nflag) // Trigger->Self (a.k.a Singular) is inherent
3169 {
3170
3/4
✓ Branch 0 taken 112 times.
✓ Branch 1 taken 14602 times.
✓ Branch 2 taken 112 times.
✗ Branch 3 not taken.
14714 if ((MAPCOMBOFLAG2(i, x, y) == mfSINGLE) && (MAPFLAG2(i, x, y) == flag))
3171 {
3172 112 rpos = COMBOPOS_REGION(x, y);
3173 112 }
3174
3/4
✓ Branch 0 taken 56 times.
✓ Branch 1 taken 14546 times.
✓ Branch 2 taken 56 times.
✗ Branch 3 not taken.
14602 else if ((MAPCOMBOFLAG2(i, x, y) == mfSINGLE16) && (MAPFLAG2(i, x, y) == flag))
3175 {
3176 56 rpos = COMBOPOS_REGION(x, y);
3177 56 single16 = true;
3178 56 }
3179 14714 }
3180
3181
2/2
✓ Branch 0 taken 97877619 times.
✓ Branch 1 taken 2723 times.
97880342 if (found_cflag) // Trigger->Self (a.k.a Singular) is non-inherent
3182 {
3183
3/4
✓ Branch 0 taken 255 times.
✓ Branch 1 taken 2468 times.
✓ Branch 2 taken 255 times.
✗ Branch 3 not taken.
2723 if ((MAPFLAG2(i, x, y) == mfSINGLE) && (MAPCOMBOFLAG2(i, x, y) == flag))
3184 {
3185 255 rpos = COMBOPOS_REGION(x, y);
3186 255 }
3187
3/4
✓ Branch 0 taken 29 times.
✓ Branch 1 taken 2439 times.
✓ Branch 2 taken 29 times.
✗ Branch 3 not taken.
2468 else if ((MAPFLAG2(i, x, y) == mfSINGLE16) && (MAPCOMBOFLAG2(i, x, y) == flag))
3188 {
3189 29 rpos = COMBOPOS_REGION(x, y);
3190 29 single16 = true;
3191 29 }
3192 2723 }
3193 97880342 }
3194
3195 13982906 out_rpos = rpos;
3196 13982906 out_single16 = single16;
3197
4/4
✓ Branch 0 taken 13980804 times.
✓ Branch 1 taken 2102 times.
✓ Branch 2 taken 13980419 times.
✓ Branch 3 taken 385 times.
13982906 return found_nflag || found_cflag || MAPFFCOMBOFLAG(x,y) == flag;
3198 13982906 }
3199
3200 4604586 bool trigger_secrets_if_flag(int32_t x, int32_t y, int32_t flag, bool setflag)
3201 {
3202
8/8
✓ Branch 0 taken 4604346 times.
✓ Branch 1 taken 240 times.
✓ Branch 2 taken 4602449 times.
✓ Branch 3 taken 1897 times.
✓ Branch 4 taken 4601929 times.
✓ Branch 5 taken 520 times.
✓ Branch 6 taken 952 times.
✓ Branch 7 taken 4600977 times.
4604586 if (x < -16 || y < -16 || x >= world_w || y >= world_h) return false;
3203
3204 4600977 mapscr* scr = NULL;
3205 4600977 int32_t screen = -1;
3206 4600977 rpos_t trigger_rpos = rpos_t::None;
3207 4600977 bool single16 = false;
3208
3209 4600977 std::vector<std::pair<int, int>> coords;
3210
1/2
✓ Branch 0 taken 4600977 times.
✗ Branch 1 not taken.
4600977 coords.push_back({x, y});
3211
1/2
✓ Branch 0 taken 4600977 times.
✗ Branch 1 not taken.
4600977 coords.push_back({x + 15, y});
3212
1/2
✓ Branch 0 taken 4600977 times.
✗ Branch 1 not taken.
4600977 coords.push_back({x, y + 15});
3213
1/2
✓ Branch 0 taken 4600977 times.
✗ Branch 1 not taken.
4600977 coords.push_back({x + 15, y + 15});
3214 4600977 std::vector<rpos_t> rposes_seen;
3215
2/2
✓ Branch 0 taken 4598479 times.
✓ Branch 1 taken 18398387 times.
87336590 for (auto [x, y] : coords)
3216 {
3217
2/4
✓ Branch 0 taken 18398387 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 18398387 times.
✗ Branch 3 not taken.
36796774 rpos_t rpos = COMBOPOS_REGION_B(x, y);
3218
2/2
✓ Branch 0 taken 18184458 times.
✓ Branch 1 taken 213929 times.
18398387 if (rpos == rpos_t::None)
3219 213929 continue;
3220
3221
4/6
✓ Branch 0 taken 18184458 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 18184458 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 11 times.
✓ Branch 5 taken 18184447 times.
36368916 if (MAPFFCOMBOFLAG(x, y) == flag)
3222 {
3223
2/4
✓ Branch 0 taken 11 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 11 times.
✗ Branch 3 not taken.
22 screen = get_screen_for_world_xy(x, y);
3224 11 break;
3225 }
3226
3227 18184447 bool seen = false;
3228
2/2
✓ Branch 0 taken 13982906 times.
✓ Branch 1 taken 22894140 times.
36877046 for (rpos_t r : rposes_seen)
3229 {
3230
2/2
✓ Branch 0 taken 18692599 times.
✓ Branch 1 taken 4201541 times.
22894140 if (r == rpos)
3231 {
3232 4201541 seen = true;
3233 4201541 break;
3234 }
3235 }
3236
2/2
✓ Branch 0 taken 13982906 times.
✓ Branch 1 taken 4201541 times.
18184447 if (seen)
3237 4201541 continue;
3238
3239
1/2
✓ Branch 0 taken 13982906 times.
✗ Branch 1 not taken.
13982906 rposes_seen.push_back(rpos);
3240
4/6
✓ Branch 0 taken 13982906 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 13982906 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2487 times.
✓ Branch 5 taken 13980419 times.
27965812 if (has_flag_trigger(x, y, flag, trigger_rpos, single16))
3241 {
3242
2/4
✓ Branch 0 taken 2487 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2487 times.
✗ Branch 3 not taken.
4974 screen = get_screen_for_world_xy(x, y);
3243 2487 break;
3244 }
3245 }
3246
3247
3/4
✓ Branch 0 taken 2498 times.
✓ Branch 1 taken 4598479 times.
✓ Branch 2 taken 2498 times.
✗ Branch 3 not taken.
4600977 if (screen != -1) scr = get_scr(screen);
3248
2/2
✓ Branch 0 taken 2498 times.
✓ Branch 1 taken 4598479 times.
4600977 if (!scr) return false;
3249
3250
2/2
✓ Branch 0 taken 2046 times.
✓ Branch 1 taken 452 times.
2498 if (trigger_rpos == rpos_t::None)
3251 {
3252 2046 checktrigger = true;
3253
1/2
✓ Branch 0 taken 2046 times.
✗ Branch 1 not taken.
2046 trigger_secrets_for_screen(TriggerSource::Unspecified, screen);
3254 2046 }
3255 else
3256 {
3257 452 checktrigger = true;
3258
2/4
✓ Branch 0 taken 452 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 452 times.
✗ Branch 3 not taken.
452 trigger_secrets_for_screen(TriggerSource::Singular, scr, single16, RPOS_TO_POS(trigger_rpos));
3259 }
3260
3261
1/2
✓ Branch 0 taken 2498 times.
✗ Branch 1 not taken.
2498 sfx(scr->secretsfx);
3262
3263
2/2
✓ Branch 0 taken 21 times.
✓ Branch 1 taken 2477 times.
2498 if(scr->flags6&fTRIGGERFPERM)
3264 {
3265
1/2
✓ Branch 0 taken 21 times.
✗ Branch 1 not taken.
21 int32_t flags_remaining = findtrigger(screen); //Normal flags
3266
3267
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 9 times.
21 if (flags_remaining)
3268 {
3269
1/2
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
12 Z_eventlog("Hit All Triggers->Perm Secret not fulfilled (%d trigger flag%s remain).\n", flags_remaining, flags_remaining>1?"s":"");
3270 12 setflag=false;
3271 12 }
3272
3273 // Only actually trigger secrets now if 1) all triggers are gone and 2) QR qr_ALLTRIG_PERMSEC_NO_TEMP is off, in
3274 // which case only the screen state for mSECRET may be set below.
3275
4/4
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 12 times.
✓ Branch 2 taken 6 times.
✓ Branch 3 taken 3 times.
21 if (!flags_remaining && !get_qr(qr_ALLTRIG_PERMSEC_NO_TEMP))
3276 {
3277
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 trigger_secrets_for_screen(TriggerSource::Unspecified, scr, scr->flags6&fTRIGGERF1631, -1);
3278 6 }
3279 21 }
3280
3281
5/6
✓ Branch 0 taken 2384 times.
✓ Branch 1 taken 114 times.
✓ Branch 2 taken 2384 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1108 times.
✓ Branch 5 taken 1276 times.
2498 if (setflag && canPermSecret(cur_dmap, screen))
3282
2/2
✓ Branch 0 taken 813 times.
✓ Branch 1 taken 463 times.
2089 if(!(scr->flags5&fTEMPSECRETS))
3283
1/2
✓ Branch 0 taken 813 times.
✗ Branch 1 not taken.
813 setmapflag(scr, mSECRET);
3284
3285 2498 return true;
3286 4604586 }
3287
3288 15386110 void update_slopes()
3289 {
3290
2/2
✓ Branch 0 taken 142356 times.
✓ Branch 1 taken 15386110 times.
15528466 for (auto& p : slopes)
3291 {
3292 142356 slope_object& s = p.second;
3293 142356 s.updateslope(); //sets old x/y poses
3294 }
3295 15386110 }
3296
3297 14928683 void update_freeform_combos()
3298 {
3299 14928683 ffscript_engine(false);
3300
2/2
✓ Branch 0 taken 24172 times.
✓ Branch 1 taken 14904511 times.
14928683 if ( !FFCore.system_suspend[susptUPDATEFFC] )
3301 {
3302 14904511 int wrap_right = world_w + 32;
3303 14904511 int wrap_bottom = world_h + 32;
3304
3305 488486203 for_every_ffc([&](const ffc_handle_t& ffc_handle) {
3306 473581692 mapscr* scr = ffc_handle.scr;
3307 473581692 ffcdata& thisffc = *ffc_handle.ffc;
3308
3309 // Combo 0?
3310
2/2
✓ Branch 0 taken 47283515 times.
✓ Branch 1 taken 426298177 times.
473581692 if(thisffc.data==0)
3311 426298177 return;
3312
3313 // Changer?
3314
2/2
✓ Branch 0 taken 562821 times.
✓ Branch 1 taken 46720694 times.
47283515 if(thisffc.flags&ffc_changer)
3315 562821 return;
3316
3317 // Stationary?
3318
2/2
✓ Branch 0 taken 9844 times.
✓ Branch 1 taken 46710850 times.
46720694 if(thisffc.flags&ffc_stationary)
3319 9844 return;
3320
3321 // Frozen because Hero's holding up an item?
3322
3/4
✓ Branch 0 taken 157429 times.
✓ Branch 1 taken 46553421 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 157429 times.
46710850 if(Hero.getHoldClk()>0 && (thisffc.flags&ffc_ignoreholdup)==0)
3323 157429 return;
3324
3325 // Check for changers
3326
2/2
✓ Branch 0 taken 31045342 times.
✓ Branch 1 taken 15508079 times.
46553421 if (thisffc.link==0)
3327 {
3328 446641935 for_some_ffcs([&](const ffc_handle_t& other_ffc_handle) {
3329
2/2
✓ Branch 0 taken 15506442 times.
✓ Branch 1 taken 415627414 times.
431133856 if (ffc_handle.id == other_ffc_handle.id)
3330 15506442 return true;
3331
3332 415627414 ffcdata& otherffc = *other_ffc_handle.ffc;
3333 // Combo 0?
3334
2/2
✓ Branch 0 taken 147056060 times.
✓ Branch 1 taken 268571354 times.
415627414 if(otherffc.data==0)
3335 268571354 return true;
3336
3337 // Not a changer?
3338
2/2
✓ Branch 0 taken 142874031 times.
✓ Branch 1 taken 4182029 times.
147056060 if(!(otherffc.flags&ffc_changer))
3339 142874031 return true;
3340
3341 // Ignore this changer?
3342
4/4
✓ Branch 0 taken 564215 times.
✓ Branch 1 taken 3617814 times.
✓ Branch 2 taken 308097 times.
✓ Branch 3 taken 3309717 times.
4182029 if((otherffc.x.getInt()==thisffc.changer_x&&otherffc.y.getInt()==thisffc.changer_y) || thisffc.flags&ffc_ignorechanger)
3343 872312 return true;
3344
3345
3/4
✓ Branch 0 taken 2870799 times.
✓ Branch 1 taken 438918 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 3663 times.
3313380 if((isonline(thisffc.x.getZLong(), thisffc.y.getZLong(), thisffc.prev_changer_x, thisffc.prev_changer_y, otherffc.x.getZLong(), otherffc.y.getZLong()) || // Along the line, or...
3346 ( // At exactly the same position,
3347
2/2
✓ Branch 0 taken 217547 times.
✓ Branch 1 taken 2653252 times.
2870799 (thisffc.x==otherffc.x && thisffc.y==otherffc.y))
3348
2/2
✓ Branch 0 taken 2435705 times.
✓ Branch 1 taken 2653252 times.
217547 ||
3349 //or imprecision and close enough
3350
0/2
✗ Branch 0 not taken.
✗ Branch 1 not taken.
5306504 ( (thisffc.flags&ffc_imprecisionchanger) && ((abs(thisffc.x.getZLong() - otherffc.x.getZLong()) < 10000) && abs(thisffc.y.getZLong() - otherffc.y.getZLong()) < 10000) )
3351 )
3352 && //and...
3353
2/2
✓ Branch 0 taken 3663 times.
✓ Branch 1 taken 2870960 times.
2874623 (thisffc.prev_changer_x>-10000000 && thisffc.prev_changer_y>-10000000)) // This isn't the first frame on this screen
3354 {
3355 3663 zc_ffc_changer(thisffc, otherffc, ffc_handle.id, other_ffc_handle.id);
3356 3663 return false;
3357 }
3358
3359 2870960 return true;
3360 430082568 });
3361 15508079 }
3362
3363
2/2
✓ Branch 0 taken 31045342 times.
✓ Branch 1 taken 15508079 times.
46553421 ffcdata* linked_ffc = thisffc.link ? get_ffc_handle(thisffc.link - 1).ffc : nullptr;
3364
4/4
✓ Branch 0 taken 15508079 times.
✓ Branch 1 taken 31045342 times.
✓ Branch 2 taken 15430786 times.
✓ Branch 3 taken 15614556 times.
46553421 if (linked_ffc ? !linked_ffc->delay : !thisffc.delay)
3365 {
3366
4/4
✓ Branch 0 taken 182609 times.
✓ Branch 1 taken 15431947 times.
✓ Branch 2 taken 85331 times.
✓ Branch 3 taken 97278 times.
15614556 if(thisffc.link && (thisffc.link-1) != ffc_handle.id)
3367 {
3368 97278 thisffc.prev_changer_x = thisffc.x.getZLong();
3369 97278 thisffc.prev_changer_y = thisffc.y.getZLong();
3370 97278 thisffc.x += linked_ffc->vx;
3371 97278 thisffc.y += linked_ffc->vy;
3372 97278 }
3373 else
3374 {
3375 15517278 thisffc.prev_changer_x = thisffc.x.getZLong();
3376 15517278 thisffc.prev_changer_y = thisffc.y.getZLong();
3377 15517278 thisffc.x += thisffc.vx;
3378 15517278 thisffc.y += thisffc.vy;
3379 15517278 thisffc.vx += thisffc.ax;
3380 15517278 thisffc.vy += thisffc.ay;
3381
3382
3383
2/2
✓ Branch 0 taken 1192093 times.
✓ Branch 1 taken 14325185 times.
15517278 if(get_qr(qr_OLD_FFC_SPEED_CAP))
3384 {
3385
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14325185 times.
14325185 if(thisffc.vx>128) thisffc.vx=128;
3386
3387
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14325185 times.
14325185 if(thisffc.vx<-128) thisffc.vx=-128;
3388
3389
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14325185 times.
14325185 if(thisffc.vy>128) thisffc.vy=128;
3390
3391
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14325185 times.
14325185 if(thisffc.vy<-128) thisffc.vy=-128;
3392 14325185 }
3393 }
3394 15614556 }
3395 else
3396 {
3397
3/4
✓ Branch 0 taken 1161 times.
✓ Branch 1 taken 76132 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1161 times.
30938865 if(!thisffc.link || (thisffc.link-1) == ffc_handle.id)
3398 76132 thisffc.delay--;
3399 }
3400
3401 // Check if the FFC's off the side of the screen
3402
3403 // Left
3404
2/2
✓ Branch 0 taken 10449 times.
✓ Branch 1 taken 15681400 times.
15691849 if(thisffc.x<-32)
3405 {
3406
2/2
✓ Branch 0 taken 253 times.
✓ Branch 1 taken 10196 times.
10449 if(scr->flags6&fWRAPAROUNDFF)
3407 {
3408 253 thisffc.x = wrap_right+(thisffc.x+32);
3409 253 thisffc.solid_update(false);
3410 253 thisffc.prev_changer_y = thisffc.y.getZLong();
3411 // Re-enable previous changer
3412 253 thisffc.changer_x = -1000;
3413 253 thisffc.changer_y = -1000;
3414 253 }
3415
2/2
✓ Branch 0 taken 10127 times.
✓ Branch 1 taken 69 times.
10196 else if(thisffc.x<-64)
3416 {
3417 69 zc_ffc_set(thisffc, 0);
3418 69 thisffc.flags&=~ffc_carryover;
3419 69 }
3420 10449 }
3421 // Right
3422
2/2
✓ Branch 0 taken 15681219 times.
✓ Branch 1 taken 181 times.
15681400 else if(thisffc.x>=wrap_right)
3423 {
3424
2/2
✓ Branch 0 taken 128 times.
✓ Branch 1 taken 53 times.
181 if(scr->flags6&fWRAPAROUNDFF)
3425 {
3426 128 thisffc.x = thisffc.x-wrap_right-32;
3427 128 thisffc.solid_update(false);
3428 128 thisffc.prev_changer_y = thisffc.y.getZLong();
3429 128 thisffc.changer_x = -1000;
3430 128 thisffc.changer_y = -1000;
3431 128 }
3432 else
3433 {
3434 53 zc_ffc_set(thisffc, 0);
3435 53 thisffc.flags&=~ffc_carryover;
3436 }
3437 181 }
3438
3439 // Top
3440
2/2
✓ Branch 0 taken 25806 times.
✓ Branch 1 taken 15666043 times.
15691849 if(thisffc.y<-32)
3441 {
3442
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 25798 times.
25806 if(scr->flags6&fWRAPAROUNDFF)
3443 {
3444 8 thisffc.y = wrap_bottom+(thisffc.y+32);
3445 8 thisffc.solid_update(false);
3446 8 thisffc.prev_changer_x = thisffc.x.getZLong();
3447 8 thisffc.changer_x = -1000;
3448 8 thisffc.changer_y = -1000;
3449 8 }
3450
2/2
✓ Branch 0 taken 25481 times.
✓ Branch 1 taken 317 times.
25798 else if(thisffc.y<-64)
3451 {
3452 317 zc_ffc_set(thisffc, 0);
3453 317 thisffc.flags&=~ffc_carryover;
3454 317 }
3455 25806 }
3456 // Bottom
3457
2/2
✓ Branch 0 taken 15665175 times.
✓ Branch 1 taken 868 times.
15666043 else if(thisffc.y>=wrap_bottom)
3458 {
3459
2/2
✓ Branch 0 taken 753 times.
✓ Branch 1 taken 115 times.
868 if(scr->flags6&fWRAPAROUNDFF)
3460 {
3461 753 thisffc.y = thisffc.y-wrap_bottom-32;
3462 753 thisffc.solid_update(false);
3463 753 thisffc.prev_changer_y = thisffc.x.getZLong();
3464 753 thisffc.changer_x = -1000;
3465 753 thisffc.changer_y = -1000;
3466 753 }
3467 else
3468 {
3469 115 zc_ffc_set(thisffc, 0);
3470 115 thisffc.flags&=~ffc_carryover;
3471 }
3472 868 }
3473 15691849 thisffc.solid_update();
3474 442720120 });
3475 14904511 }
3476 14928683 }
3477
3478 bool hitflag(int32_t x, int32_t y, int32_t flagtype, byte layers)
3479 {
3480 for(int q = 0; q < 7; ++q)
3481 {
3482 if(layers&(1<<q)) //if layer is to be checked
3483 if(MAPFLAG2(q-1,x,y)==flagtype||MAPCOMBOFLAG2(q-1,x,y)==flagtype) //matching flag
3484 return true;
3485 }
3486 return false;
3487 }
3488
3489 231 optional<int> nextscr(int screen, int dir)
3490 {
3491 231 auto [m, s] = nextscr2(cur_map, screen, dir);
3492
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 231 times.
231 if (m == -1) return nullopt;
3493 462 return (m<<7) + s;
3494 231 }
3495
3496 1064 std::pair<int32_t, int32_t> nextscr2(int32_t dir)
3497 {
3498 1064 int32_t map = cur_map;
3499
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1064 times.
1064 int32_t screen = screenscrolling ? scrolling_hero_screen : Hero.current_screen;
3500 1064 return nextscr2(map, screen, dir);
3501 }
3502
3503 5582 std::pair<int32_t, int32_t> nextscr2(int map, int screen, int32_t dir)
3504 {
3505 5582 screen = screen_index_direction(screen, (direction)dir);
3506
3507 // need to check for screens on other maps, 's' not valid, etc.
3508 5582 int32_t index = (hero_scr->sidewarpindex >> (dir*2))&3;
3509
3510 // Fun fact: when a scrolling warp is triggered, this function
3511 // is never even called! - Saf
3512
2/2
✓ Branch 0 taken 3330 times.
✓ Branch 1 taken 2252 times.
6126 if(hero_scr->sidewarptype[index] == 3) // scrolling warp
3513 {
3514
4/5
✗ Branch 0 not taken.
✓ Branch 1 taken 482 times.
✓ Branch 2 taken 527 times.
✓ Branch 3 taken 546 times.
✓ Branch 4 taken 697 times.
2252 switch(dir)
3515 {
3516 case up:
3517
2/2
✓ Branch 0 taken 83 times.
✓ Branch 1 taken 399 times.
482 if(!(hero_scr->flags2&wfUP)) goto nowarp;
3518
3519 83 break;
3520
3521 case down:
3522
2/2
✓ Branch 0 taken 79 times.
✓ Branch 1 taken 448 times.
527 if(!(hero_scr->flags2&wfDOWN)) goto nowarp;
3523
3524 79 break;
3525
3526 case left:
3527
2/2
✓ Branch 0 taken 209 times.
✓ Branch 1 taken 337 times.
546 if(!(hero_scr->flags2&wfLEFT)) goto nowarp;
3528
3529 209 break;
3530
3531 case right:
3532
2/2
✓ Branch 0 taken 173 times.
✓ Branch 1 taken 524 times.
697 if(!(hero_scr->flags2&wfRIGHT)) goto nowarp;
3533
3534 173 break;
3535 }
3536
3537 544 map = DMaps[hero_scr->sidewarpdmap[index]].map;
3538 544 screen = hero_scr->sidewarpscr[index] + DMaps[hero_scr->sidewarpdmap[index]].xoff;
3539 544 }
3540
3541 nowarp:
3542
4/4
✓ Branch 0 taken 5518 times.
✓ Branch 1 taken 64 times.
✓ Branch 2 taken 112 times.
✓ Branch 3 taken 5406 times.
5582 if(screen<0||screen>=128)
3543 176 return {-1, -1};
3544
3545 5406 return {map, screen};
3546 5582 }
3547
3548 403 optional<int> nextscr_mi(int mi, int dir)
3549 {
3550 403 int map = mi/MAPSCRSNORMAL;
3551 403 int screen = mi%MAPSCRSNORMAL;
3552 403 auto [m, s] = nextscr2(map, screen, dir);
3553
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 402 times.
403 if (m == -1) return nullopt;
3554 804 return (m<<7) + s;
3555 403 }
3556
3557 2297 void bombdoor(int32_t x,int32_t y)
3558 {
3559
2/2
✓ Branch 0 taken 2276 times.
✓ Branch 1 taken 21 times.
2297 if (!is_in_world_bounds(x, y))
3560 21 return;
3561
3562 2276 auto rpos_handle = get_rpos_handle_for_world_xy(x, y, 0);
3563 2276 mapscr* scr = rpos_handle.scr;
3564 2276 int screen = scr->screen;
3565 3084 auto [x0, y0] = translate_screen_coordinates_to_world(rpos_handle.screen);
3566 #define CHECK_RECT(x,y,rx1,ry1,rx2,ry2) (isinRect(x,y,x0+rx1,y0+ry1,x0+rx2,y0+ry2))
3567
3568
12/12
✓ Branch 0 taken 79 times.
✓ Branch 1 taken 2197 times.
✓ Branch 2 taken 10 times.
✓ Branch 3 taken 69 times.
✓ Branch 4 taken 10 times.
✓ Branch 5 taken 69 times.
✓ Branch 6 taken 10 times.
✓ Branch 7 taken 69 times.
✓ Branch 8 taken 10 times.
✓ Branch 9 taken 69 times.
✓ Branch 10 taken 10 times.
✓ Branch 11 taken 69 times.
2276 if(scr->door[0]==dBOMB && CHECK_RECT(x,y,100,0,139,48))
3569 {
3570 69 scr->door[0]=dBOMBED;
3571 69 putdoor(scr, scrollbuf, 0, dBOMBED);
3572 69 setmapflag(scr, mDOOR_UP);
3573 69 markBmap(-1, screen);
3574
3575
1/2
✓ Branch 0 taken 69 times.
✗ Branch 1 not taken.
69 if(auto v = nextscr(screen, up))
3576 {
3577 69 setmapflag_mi(*v, mDOOR_DOWN);
3578 69 markBmap(-1,*v-(get_currdmap()<<7));
3579 69 }
3580 69 }
3581
3582
12/12
✓ Branch 0 taken 49 times.
✓ Branch 1 taken 2227 times.
✓ Branch 2 taken 10 times.
✓ Branch 3 taken 39 times.
✓ Branch 4 taken 10 times.
✓ Branch 5 taken 39 times.
✓ Branch 6 taken 10 times.
✓ Branch 7 taken 39 times.
✓ Branch 8 taken 10 times.
✓ Branch 9 taken 39 times.
✓ Branch 10 taken 10 times.
✓ Branch 11 taken 39 times.
2276 if(scr->door[1]==dBOMB && CHECK_RECT(x,y,100,112,139,176))
3583 {
3584 39 scr->door[1]=dBOMBED;
3585 39 putdoor(scr, scrollbuf, 1, dBOMBED);
3586 39 setmapflag(scr, mDOOR_DOWN);
3587 39 markBmap(-1, rpos_handle.screen);
3588
3589
1/2
✓ Branch 0 taken 39 times.
✗ Branch 1 not taken.
39 if(auto v = nextscr(rpos_handle.screen, down))
3590 {
3591 39 setmapflag_mi(*v, mDOOR_UP);
3592 39 markBmap(-1,*v-(get_currdmap()<<7));
3593 39 }
3594 39 }
3595
3596
12/12
✓ Branch 0 taken 67 times.
✓ Branch 1 taken 2209 times.
✓ Branch 2 taken 16 times.
✓ Branch 3 taken 51 times.
✓ Branch 4 taken 16 times.
✓ Branch 5 taken 51 times.
✓ Branch 6 taken 16 times.
✓ Branch 7 taken 51 times.
✓ Branch 8 taken 16 times.
✓ Branch 9 taken 51 times.
✓ Branch 10 taken 16 times.
✓ Branch 11 taken 51 times.
2276 if(scr->door[2]==dBOMB && CHECK_RECT(x,y,0,60,48,98))
3597 {
3598 51 scr->door[2]=dBOMBED;
3599 51 putdoor(scr, scrollbuf, 2, dBOMBED);
3600 51 setmapflag(scr, mDOOR_LEFT);
3601 51 markBmap(-1, rpos_handle.screen);
3602
3603
1/2
✓ Branch 0 taken 51 times.
✗ Branch 1 not taken.
51 if(auto v = nextscr(rpos_handle.screen, left))
3604 {
3605 51 setmapflag_mi(*v, mDOOR_RIGHT);
3606 51 markBmap(-1,*v-(get_currdmap()<<7));
3607 51 }
3608 51 }
3609
3610
12/12
✓ Branch 0 taken 86 times.
✓ Branch 1 taken 2190 times.
✓ Branch 2 taken 14 times.
✓ Branch 3 taken 72 times.
✓ Branch 4 taken 14 times.
✓ Branch 5 taken 72 times.
✓ Branch 6 taken 14 times.
✓ Branch 7 taken 72 times.
✓ Branch 8 taken 14 times.
✓ Branch 9 taken 72 times.
✓ Branch 10 taken 14 times.
✓ Branch 11 taken 72 times.
2276 if(scr->door[3]==dBOMB && CHECK_RECT(x,y,192,60,240,98))
3611 {
3612 72 scr->door[3]=dBOMBED;
3613 72 putdoor(scr, scrollbuf, 3, dBOMBED);
3614 72 setmapflag(scr, mDOOR_RIGHT);
3615 72 markBmap(-1, rpos_handle.screen);
3616
3617
1/2
✓ Branch 0 taken 72 times.
✗ Branch 1 not taken.
72 if(auto v = nextscr(rpos_handle.screen, right))
3618 {
3619 72 setmapflag_mi(*v, mDOOR_LEFT);
3620 72 markBmap(-1,*v-(get_currdmap()<<7));
3621 72 }
3622 72 }
3623 2297 }
3624
3625 7119005457 void draw_cmb(BITMAP* dest, int32_t x, int32_t y, int32_t cid, int32_t cset,
3626 bool over, bool transp)
3627 {
3628 7119005457 auto& cmb = combobuf[cid];
3629
2/2
✓ Branch 0 taken 93673 times.
✓ Branch 1 taken 7118911784 times.
7119005457 if(cmb.animflags & AF_EDITOR_ONLY)
3630 93673 return;
3631
2/2
✓ Branch 0 taken 3924435462 times.
✓ Branch 1 taken 3194476322 times.
7118911784 if(over)
3632 {
3633
2/2
✓ Branch 0 taken 841117 times.
✓ Branch 1 taken 3923594345 times.
3924435462 if(cmb.animflags & AF_TRANSPARENT)
3634 841117 transp = !transp;
3635
2/2
✓ Branch 0 taken 328615081 times.
✓ Branch 1 taken 3595820381 times.
3924435462 if(transp)
3636 328615081 overcombotranslucent(dest, x, y, cid, cset, 128);
3637 3595820381 else overcombo(dest, x, y, cid, cset);
3638 3924435462 }
3639 3194476322 else putcombo(dest, x, y, cid, cset);
3640 7119005457 }
3641 7119013905 void draw_cmb_pos(BITMAP* dest, int32_t x, int32_t y, rpos_t rpos, int32_t cid,
3642 int32_t cset, byte layer, bool over, bool transp)
3643 {
3644
2/2
✓ Branch 0 taken 847534117 times.
✓ Branch 1 taken 6271479788 times.
7119013905 if (rpos != rpos_t::None)
3645 {
3646 6271479788 rpos_t plrpos = COMBOPOS_REGION_B(Hero.x+8, Hero.y+8);
3647
2/2
✓ Branch 0 taken 749524 times.
✓ Branch 1 taken 6270730264 times.
6271479788 if (plrpos != rpos_t::None)
3648 {
3649 6270730264 bool dosw = false;
3650
4/4
✓ Branch 0 taken 67998 times.
✓ Branch 1 taken 6270662266 times.
✓ Branch 2 taken 59550 times.
✓ Branch 3 taken 8448 times.
6270730264 if (rpos == hooked_comborpos && (hooked_layerbits & (1<<layer)))
3651 {
3652
1/2
✓ Branch 0 taken 8448 times.
✗ Branch 1 not taken.
8448 if(hooked_undercombos[layer] > -1)
3653 {
3654 draw_cmb(dest, x, y,
3655 hooked_undercombos[layer], hooked_undercombos[layer+7], over, transp);
3656 }
3657 8448 dosw = true;
3658 8448 }
3659
4/4
✓ Branch 0 taken 35595934 times.
✓ Branch 1 taken 6235125882 times.
✓ Branch 2 taken 8448 times.
✓ Branch 3 taken 35587486 times.
6270721816 else if (rpos == plrpos && (hooked_layerbits & (1<<(layer+8))))
3660 {
3661 8448 dosw = true;
3662 8448 }
3663
2/2
✓ Branch 0 taken 6270713368 times.
✓ Branch 1 taken 16896 times.
6270730264 if (dosw)
3664 {
3665
1/4
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✓ Branch 2 taken 16896 times.
✗ Branch 3 not taken.
16896 switch (Hero.switchhookstyle)
3666 {
3667 default: case swPOOF:
3668 break; //Nothing special here
3669 case swFLICKER:
3670 {
3671
2/2
✓ Branch 0 taken 8448 times.
✓ Branch 1 taken 8448 times.
16896 if(abs(Hero.switchhookclk-33)&0b1000)
3672 8448 break; //Drawn this frame
3673 8448 return; //Not drawn this frame
3674 }
3675 case swRISE:
3676 {
3677 //Draw rising up
3678 y -= 8-(abs(Hero.switchhookclk-32)/4);
3679 break;
3680 }
3681 }
3682 8448 }
3683 6270721816 }
3684 6271471340 }
3685
3686 7119005457 draw_cmb(dest, x, y, cid, cset, over, transp);
3687 7119013905 }
3688
3689 // `draw_cmb_pos` only does meaningful work if the combo being drawn is within the bounds of
3690 // the `bmp` bitmap. However, even getting to the point where `puttile16` (for example) knows
3691 // to cull is somewhat expensive. Since it can only draw 16x16 pixels, we can do the equivalent
3692 // culling here by determining the rows/columns that are within the bitmap bounds. This nets
3693 // on the order of ~30 FPS in uncapped mode on my machine, depending on the viewport/region size.
3694 //
3695 // These two inequalities must be true for `draw_cmb_pos` to do anything useful:
3696 //
3697 // -16 < comboPositionX*16 + x < bitmapWidth
3698 // -16 < comboPositionY*16 + y < bitmapHeight
3699 //
3700 // The following start/end values are derived directly from the above.
3701 //
3702 // `x` and `y` are the offsets the combos will be drawn into the bitmap.
3703 44030269 static void get_bounds_for_draw_cmb_calls(BITMAP* bmp, int x, int y, int& start_x, int& end_x, int& start_y, int& end_y)
3704 {
3705 // if (bmp->clip)
3706 // {
3707 // start_x = MAX(0, ceil((bmp->cl - 15 - x) / 16.0));
3708 // end_x = MIN(16, ceil((bmp->cr - x) / 16.0));
3709 // start_y = MAX(0, ceil((bmp->ct - 15 - y) / 16.0));
3710 // end_y = MIN(11, ceil((bmp->cb - y) / 16.0));
3711 // return;
3712 // }
3713
3714
2/2
✓ Branch 0 taken 2404962 times.
✓ Branch 1 taken 41625307 times.
44030269 start_x = MAX(0, ceil((-15 - x) / 16.0));
3715
2/2
✓ Branch 0 taken 2412938 times.
✓ Branch 1 taken 41617331 times.
44030269 end_x = MIN(16, ceil((bmp->w - x) / 16.0));
3716
2/2
✓ Branch 0 taken 42491720 times.
✓ Branch 1 taken 1538549 times.
44030269 start_y = MAX(0, ceil((-15 - y) / 16.0));
3717
2/2
✓ Branch 0 taken 1874535 times.
✓ Branch 1 taken 42155734 times.
44030269 end_y = MIN(11, ceil((bmp->h - y) / 16.0));
3718 44030269 }
3719
3720 195676018 void do_ffc_layer(BITMAP* bmp, int32_t layer, const screen_handle_t& screen_handle, int32_t x, int32_t y)
3721 {
3722
1/2
✓ Branch 0 taken 195676018 times.
✗ Branch 1 not taken.
195676018 if(!show_ffcs) return;
3723 195676018 mapscr* scr = screen_handle.scr;
3724 195676018 mapscr* base_scr = screen_handle.base_scr;
3725
3726 195676018 y += playing_field_offset;
3727
3728 195676018 bool is_overhead = layer == -1000;
3729
2/2
✓ Branch 0 taken 53237606 times.
✓ Branch 1 taken 142438412 times.
195676018 bool is_bg_layer = layer < 0 && !is_overhead;
3730
2/2
✓ Branch 0 taken 35527074 times.
✓ Branch 1 taken 160148944 times.
195676018 int real_layer = is_bg_layer ? abs(layer) : layer;
3731
2/2
✓ Branch 0 taken 195676018 times.
✓ Branch 1 taken 5610067558 times.
5805743576 for(int32_t i = (base_scr->numFFC()-1); i >= 0; --i)
3732 {
3733
2/2
✓ Branch 0 taken 217455144 times.
✓ Branch 1 taken 5392612414 times.
5610067558 if (base_scr->ffcs[i].data == 0)
3734 5392612414 continue;
3735
3/4
✓ Branch 0 taken 39536116 times.
✓ Branch 1 taken 177919028 times.
✓ Branch 2 taken 39536116 times.
✗ Branch 3 not taken.
217455144 if (is_bg_layer && base_scr->ffcs[i].layer == layer)
3736 ; // ffc is set negative, skip bg layer flag checks
3737 else
3738 {
3739
4/4
✓ Branch 0 taken 39536089 times.
✓ Branch 1 taken 177919055 times.
✓ Branch 2 taken 19768058 times.
✓ Branch 3 taken 19768031 times.
217455144 if(real_layer == 2 && (is_bg_layer != XOR(base_scr->flags7&fLAYER2BG, DMaps[cur_dmap].flags&dmfLAYER2BG)))
3740 19768031 continue;
3741
4/4
✓ Branch 0 taken 39535883 times.
✓ Branch 1 taken 158151230 times.
✓ Branch 2 taken 19768058 times.
✓ Branch 3 taken 19767825 times.
197687113 else if (real_layer == 3 && (is_bg_layer != XOR(base_scr->flags7&fLAYER3BG, DMaps[cur_dmap].flags&dmfLAYER3BG)))
3742 19767825 continue;
3743
4/4
✓ Branch 0 taken 158156192 times.
✓ Branch 1 taken 19763096 times.
✓ Branch 2 taken 19768058 times.
✓ Branch 3 taken 138388134 times.
177919288 if (real_layer > -1 && base_scr->ffcs[i].layer != real_layer)
3744 138388134 continue;
3745 }
3746
3747
6/6
✓ Branch 0 taken 3311080 times.
✓ Branch 1 taken 36220074 times.
✓ Branch 2 taken 5110 times.
✓ Branch 3 taken 3305970 times.
✓ Branch 4 taken 2626 times.
✓ Branch 5 taken 2484 times.
39531154 if (screenscrolling && (base_scr->ffcs[i].flags & ffc_carryover) != 0 && screen_handle.screen != scrolling_hero_screen)
3748 2484 continue; //If scrolling, only draw carryover ffcs from newscr and not oldscr.
3749
3750 39528670 base_scr->ffcs[i].draw_ffc(bmp, x, y, is_overhead);
3751 39528670 }
3752 195676018 }
3753 177484486 void _do_current_ffc_layer(BITMAP* bmp, int32_t layer)
3754 {
3755
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 177484486 times.
177484486 if(!show_ffcs) return;
3756 359893914 for_every_base_screen_in_region([&](mapscr* base_scr, unsigned int region_scr_x, unsigned int region_scr_y) {
3757 182409428 screen_handle_t handle = {base_scr, base_scr, base_scr->screen, 0};
3758 182409428 do_ffc_layer(bmp, layer, handle, 0, 0);
3759 182409428 });
3760 177484486 }
3761 110479810 void do_scrolling_layer(BITMAP *bmp, int32_t type, const screen_handle_t& screen_handle, int32_t x, int32_t y)
3762 {
3763 110479810 mapscr* scr = screen_handle.scr;
3764 110479810 mapscr* base_scr = screen_handle.base_scr;
3765
3766
4/4
✓ Branch 0 taken 69324458 times.
✓ Branch 1 taken 41155352 times.
✓ Branch 2 taken 41155352 times.
✓ Branch 3 taken 110479810 times.
110479810 if (type == -3 || type == -4)
3767 {
3768 82310704 y += playing_field_offset;
3769
3770
0/2
✗ Branch 0 not taken.
✗ Branch 1 not taken.
82310704 for(int32_t i = (base_scr->numFFC()-1); i >= 0; --i)
3771 {
3772 if (base_scr->ffcs[i].data == 0)
3773 continue;
3774
3775 if (screenscrolling && (base_scr->ffcs[i].flags & ffc_carryover) != 0 && screen_handle.screen != scrolling_hero_screen)
3776 continue; //If scrolling, only draw carryover ffcs from newscr and not oldscr.
3777
3778 base_scr->ffcs[i].draw_ffc(bmp, x, y, (type==-4));
3779 }
3780 return;
3781 }
3782
3783 110479810 x -= viewport.x;
3784 110479810 y -= viewport.y - playing_field_offset;
3785
3786 110479810 bool over = true, transp = false;
3787 110479810 int layer = screen_handle.layer;
3788
3789
7/8
✓ Branch 0 taken 86213224 times.
✓ Branch 1 taken 24266586 times.
✓ Branch 2 taken 15025887 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 62897319 times.
✓ Branch 5 taken 23315905 times.
✓ Branch 6 taken 3907230 times.
✓ Branch 7 taken 5333469 times.
110479810 switch(type ? type : layer)
3790 {
3791 case -2: //push blocks
3792
2/2
✓ Branch 0 taken 21741967 times.
✓ Branch 1 taken 41155352 times.
62897319 if (scr)
3793 {
3794
2/2
✓ Branch 0 taken 3826586192 times.
✓ Branch 1 taken 62084555 times.
3863001579 for(int32_t i=0; i<176; i++)
3795 {
3796 3826586192 int32_t mf=scr->sflag[i], mf2 = combobuf[scr->data[i]].flag;
3797
3798
10/10
✓ Branch 0 taken 3826415848 times.
✓ Branch 1 taken 170344 times.
✓ Branch 2 taken 3824938643 times.
✓ Branch 3 taken 1477205 times.
✓ Branch 4 taken 3824305404 times.
✓ Branch 5 taken 633239 times.
✓ Branch 6 taken 53394531 times.
✓ Branch 7 taken 3770910873 times.
✓ Branch 8 taken 100280201 times.
✓ Branch 9 taken 57521370 times.
3870177705 if(mf==mfPUSHUD || mf==mfPUSH4 || mf==mfPUSHED || ((mf>=mfPUSHLR)&&(mf<=mfPUSHRINS))
3799
6/8
✓ Branch 0 taken 3821422755 times.
✓ Branch 1 taken 50511882 times.
✓ Branch 2 taken 3821422755 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 3821422755 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 43591513 times.
✓ Branch 7 taken 3777831242 times.
3824305404 || mf2==mfPUSHUD || mf2==mfPUSH4 || mf2==mfPUSHED || ((mf2>=mfPUSHLR)&&(mf2<=mfPUSHRINS)))
3800 {
3801
4/4
✓ Branch 0 taken 5124570 times.
✓ Branch 1 taken 782430 times.
✓ Branch 2 taken 3849 times.
✓ Branch 3 taken 5120721 times.
206467402 auto rpos = screenscrolling || ViewingMap ? rpos_t::None : POS_TO_RPOS(i, screen_handle.screen);
3802 5907000 draw_cmb_pos(bmp, x + COMBOX(i), y + COMBOY(i), rpos, scr->data[i], scr->cset[i], layer, true, false);
3803 5907000 }
3804 3841259612 }
3805 62084555 }
3806 103239907 return;
3807
3808 case -1: //over combo
3809
1/2
✓ Branch 0 taken 23315905 times.
✗ Branch 1 not taken.
23315905 if (scr)
3810 {
3811
2/2
✓ Branch 0 taken 4103599280 times.
✓ Branch 1 taken 23315905 times.
4126915185 for(int32_t i=0; i<176; i++)
3812 {
3813
2/2
✓ Branch 0 taken 4084269360 times.
✓ Branch 1 taken 19329920 times.
4103599280 if(combo_class_buf[combobuf[scr->data[i]].type].overhead)
3814 {
3815
4/4
✓ Branch 0 taken 15574819 times.
✓ Branch 1 taken 3755101 times.
✓ Branch 2 taken 22336 times.
✓ Branch 3 taken 15552483 times.
19329920 auto rpos = screenscrolling || ViewingMap ? rpos_t::None : POS_TO_RPOS(i, screen_handle.screen);
3816 19329920 draw_cmb_pos(bmp, x + COMBOX(i), y + COMBOY(i), rpos, scr->data[i], scr->cset[i], layer, true, false);
3817 19329920 }
3818 4103599280 }
3819 23315905 }
3820 23315905 return;
3821
3822 case 1:
3823 case 4:
3824 case 5:
3825 case 6:
3826
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 15025887 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
15025887 if(TransLayers || base_scr->layeropacity[layer-1]==255)
3827 {
3828
1/2
✓ Branch 0 taken 15025887 times.
✗ Branch 1 not taken.
15025887 if (scr)
3829 {
3830
2/2
✓ Branch 0 taken 13331185 times.
✓ Branch 1 taken 1694702 times.
15025887 if(base_scr->layeropacity[layer-1]!=255)
3831 1694702 transp = true;
3832 15025887 break;
3833 }
3834 }
3835 return;
3836
3837 case 2:
3838
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 3907230 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
3907230 if(TransLayers || base_scr->layeropacity[layer-1]==255)
3839 {
3840
1/2
✓ Branch 0 taken 3907230 times.
✗ Branch 1 not taken.
3907230 if (scr)
3841 {
3842
2/2
✓ Branch 0 taken 3670944 times.
✓ Branch 1 taken 236286 times.
3907230 if(base_scr->layeropacity[layer-1]!=255)
3843 236286 transp = true;
3844
3845
2/2
✓ Branch 0 taken 3759775 times.
✓ Branch 1 taken 147455 times.
3907230 if(XOR(base_scr->flags7&fLAYER2BG, DMaps[cur_dmap].flags&dmfLAYER2BG))
3846 147455 over = false;
3847
3848 3907230 break;
3849 }
3850 }
3851 return;
3852
3853 case 3:
3854
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 5333469 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
5333469 if(TransLayers || base_scr->layeropacity[layer-1]==255)
3855 {
3856
1/2
✓ Branch 0 taken 5333469 times.
✗ Branch 1 not taken.
5333469 if (scr)
3857 {
3858
2/2
✓ Branch 0 taken 5258193 times.
✓ Branch 1 taken 75276 times.
5333469 if(base_scr->layeropacity[layer-1]!=255)
3859 75276 transp = true;
3860
3861
2/2
✓ Branch 0 taken 36654 times.
✓ Branch 1 taken 237618 times.
5333469 if(XOR(base_scr->flags7&fLAYER3BG, DMaps[cur_dmap].flags&dmfLAYER3BG)
3862
2/2
✓ Branch 0 taken 274272 times.
✓ Branch 1 taken 5059197 times.
5333469 && !XOR(base_scr->flags7&fLAYER2BG, DMaps[cur_dmap].flags&dmfLAYER2BG))
3863 237618 over = false;
3864
3865 5333469 break;
3866 }
3867 }
3868 return;
3869 }
3870
3871 int start_x, end_x, start_y, end_y;
3872 24266586 get_bounds_for_draw_cmb_calls(bmp, x, y, start_x, end_x, start_y, end_y);
3873
2/2
✓ Branch 0 taken 24266586 times.
✓ Branch 1 taken 257467292 times.
281733878 for (int cy = start_y; cy < end_y; cy++)
3874 {
3875
2/2
✓ Branch 0 taken 3897791767 times.
✓ Branch 1 taken 257467292 times.
4155259059 for (int cx = start_x; cx < end_x; cx++)
3876 {
3877 3897791767 int i = cx + cy*16;
3878
4/4
✓ Branch 0 taken 3440940732 times.
✓ Branch 1 taken 456851035 times.
✓ Branch 2 taken 11831072 times.
✓ Branch 3 taken 3429109660 times.
3897791767 auto rpos = screenscrolling || ViewingMap ? rpos_t::None : POS_TO_RPOS(i, screen_handle.screen);
3879 3897791767 draw_cmb_pos(bmp, x + COMBOX(i), y + COMBOY(i), rpos, scr->data[i], scr->cset[i], layer, over, transp);
3880 3897791767 }
3881 257467292 }
3882 69324458 }
3883
3884 279475855 bool lenscheck(mapscr* scr, int layer)
3885 {
3886
4/4
✓ Branch 0 taken 279299283 times.
✓ Branch 1 taken 176572 times.
✓ Branch 2 taken 176572 times.
✓ Branch 3 taken 279475855 times.
279475855 if(layer < 0 || layer > 6) return true;
3887
2/2
✓ Branch 0 taken 259638675 times.
✓ Branch 1 taken 19837180 times.
279475855 if(get_qr(qr_OLD_LENS_LAYEREFFECT))
3888 {
3889
2/2
✓ Branch 0 taken 209750029 times.
✓ Branch 1 taken 49888646 times.
259638675 if(!layer) return true;
3890
8/8
✓ Branch 0 taken 34929361 times.
✓ Branch 1 taken 174820668 times.
✓ Branch 2 taken 258970 times.
✓ Branch 3 taken 34670391 times.
✓ Branch 4 taken 146134 times.
✓ Branch 5 taken 259680 times.
✓ Branch 6 taken 326536 times.
✓ Branch 7 taken 34489989 times.
209750029 if((layer==(int32_t)(scr->lens_layer&7)+1) && ((scr->lens_layer&llLENSSHOWS && !lensclk) || (scr->lens_layer&llLENSHIDES && lensclk)))
3891 586216 return false;
3892 209310657 }
3893 else
3894 {
3895
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 19837180 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 19837180 times.
19837180 if((lensclk ? scr->lens_hide : scr->lens_show) & (1<<layer))
3896 return false;
3897 }
3898 229147837 return true;
3899 279299283 }
3900
3901 165121217 void do_layer(BITMAP *bmp, int32_t type, const screen_handle_t& screen_handle, int32_t x, int32_t y)
3902 {
3903 165121217 bool showlayer = true;
3904 165121217 mapscr* base_scr = screen_handle.base_scr;
3905 165121217 int layer = screen_handle.layer;
3906
2/2
✓ Branch 0 taken 46563401 times.
✓ Branch 1 taken 118557816 times.
165121217 int target = type ? type : layer;
3907
3/4
✓ Branch 0 taken 118557816 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 22473017 times.
✓ Branch 3 taken 24090384 times.
165121217 switch(target)
3908 {
3909 case -2:
3910
1/2
✓ Branch 0 taken 22473017 times.
✗ Branch 1 not taken.
22473017 if(!show_layer_push)
3911 showlayer = false;
3912 22473017 break;
3913
3914 case -1:
3915
1/2
✓ Branch 0 taken 24090384 times.
✗ Branch 1 not taken.
24090384 if(!show_layer_over)
3916 showlayer = false;
3917 24090384 break;
3918
3919 case 1: case 2: case 3:
3920 case 4: case 5: case 6:
3921 118557816 showlayer = show_layers[target];
3922 118557816 break;
3923 }
3924
3925
2/2
✓ Branch 0 taken 46563401 times.
✓ Branch 1 taken 118557816 times.
165121217 if(!type)
3926 {
3927
2/2
✓ Branch 0 taken 118421618 times.
✓ Branch 1 taken 136198 times.
118557816 if(!lenscheck(base_scr,layer))
3928 136198 showlayer = false;
3929 118557816 }
3930
3931
2/2
✓ Branch 0 taken 136198 times.
✓ Branch 1 taken 164985019 times.
165121217 if(showlayer)
3932 {
3933
6/6
✓ Branch 0 taken 69416406 times.
✓ Branch 1 taken 95568613 times.
✓ Branch 2 taken 24358534 times.
✓ Branch 3 taken 45057872 times.
✓ Branch 4 taken 91948 times.
✓ Branch 5 taken 24266586 times.
164985019 if (screen_handle.scr && (type || !(base_scr->hidelayers & (1 << (layer)))))
3934 {
3935 69324458 do_scrolling_layer(bmp, type, screen_handle, x, y);
3936
4/4
✓ Branch 0 taken 24266586 times.
✓ Branch 1 taken 45057872 times.
✓ Branch 2 taken 22269756 times.
✓ Branch 3 taken 1996830 times.
69324458 if(!type && !get_qr(qr_PUSHBLOCK_SPRITE_LAYER))
3937
2/2
✓ Branch 0 taken 1996254 times.
✓ Branch 1 taken 576 times.
1997406 if(mblock2.draw(bmp,layer))
3938 576 do_primitives(bmp, SPLAYER_MOVINGBLOCK);
3939 69324458 }
3940 164985019 }
3941 165121217 }
3942
3943 107012194 void do_layer_primitives(BITMAP *bmp, int32_t layer)
3944 {
3945 107012194 bool showlayer = true;
3946
3947
2/4
✓ Branch 0 taken 107012194 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 107012194 times.
107012194 if(layer >= 0 && layer <= 6)
3948 {
3949 107012194 showlayer = show_layers[layer];
3950
3951
2/2
✓ Branch 0 taken 106885592 times.
✓ Branch 1 taken 126602 times.
107012194 if(!lenscheck(origin_scr,layer))
3952 126602 showlayer = false;
3953 107012194 }
3954
3955
2/2
✓ Branch 0 taken 126602 times.
✓ Branch 1 taken 106885592 times.
107012194 if (showlayer)
3956 106885592 do_primitives(bmp, layer);
3957 107012194 }
3958
3959 // Called by do_walkflags
3960 void put_walkflags(BITMAP *dest,int32_t x,int32_t y,int32_t xofs,int32_t yofs, word cmbdat,int32_t lyr)
3961 {
3962 newcombo const &c = combobuf[cmbdat];
3963
3964 if (c.type == cBRIDGE && get_qr(qr_OLD_BRIDGE_COMBOS)) return;
3965
3966 int32_t xx = x-xofs;
3967 int32_t yy = y+playing_field_offset-yofs;
3968
3969 int32_t bridgedetected = 0;
3970
3971 for(int32_t i=0; i<4; i++)
3972 {
3973 int32_t tx=((i&2)<<2)+xx - viewport.x;
3974 int32_t ty=((i&1)<<3)+yy - viewport.y;
3975 int32_t tx2=((i&2)<<2)+x - viewport.x;
3976 int32_t ty2=((i&1)<<3)+y - viewport.y;
3977 for (int32_t j = lyr-1; j <= 1; j++)
3978 {
3979 if (get_qr(qr_OLD_BRIDGE_COMBOS))
3980 {
3981 if (combobuf[MAPCOMBO2(j,tx2,ty2)].type == cBRIDGE && !_walkflag_layer(tx2,ty2,j))
3982 {
3983 bridgedetected |= (1<<i);
3984 }
3985 }
3986 else
3987 {
3988 if (combobuf[MAPCOMBO2(j,tx2,ty2)].type == cBRIDGE && _effectflag_layer(tx2,ty2,j))
3989 {
3990 bridgedetected |= (1<<i);
3991 }
3992 }
3993 }
3994 if ((bridgedetected & (1<<i)))
3995 {
3996 if (i >= 3) break;
3997 else continue;
3998 }
3999 bool doladdercheck = true;
4000
4001 if ((c.walk&(1<<(i+4))) && ((c.walk&(1<<i) && ((c.usrflags&cflag4)) && c.type == cWATER) || c.type == cSHALLOWWATER))
4002 {
4003 for(int32_t k=0; k<8; k+=2)
4004 for(int32_t j=0; j<8; j+=2)
4005 if(((k+j)/2)%2)
4006 rectfill(dest,tx+k,ty+j,tx+k+1,ty+j+1,makecol(85,85,255));
4007 }
4008 if (iswater_type(c.type) && !DRIEDLAKE && !((c.walk&(1<<(i+4))) && ((c.walk&(1<<i) && ((c.usrflags&cflag3) || (c.usrflags&cflag4)) && c.type == cWATER)))) //Yes, I realize this is horribly inaccurate; the alternative is the game chugging every time you turn on walk cheats.
4009 {
4010 if (get_qr(qr_NO_SOLID_SWIM)) doladdercheck = false;
4011 if((lyr==0 || (get_qr(qr_WATER_ON_LAYER_1) && lyr == 1) || (get_qr(qr_WATER_ON_LAYER_2) && lyr == 2)) && get_qr(qr_DROWN))
4012 rectfill(dest,tx,ty,tx+7,ty+7,makecol(85,85,255));
4013 else rectfill(dest,tx,ty,tx+7,ty+7,makecol(170,170,170));
4014 }
4015
4016 if(c.walk&(1<<i) && !(iswater_type(c.type) && DRIEDLAKE) && !((c.walk&(1<<(i+4))) && ((c.walk&(1<<i) && ((c.usrflags&cflag3) || (c.usrflags&cflag4)) && c.type == cWATER)))) // Check for dried lake (watertype && not water)
4017 {
4018 if(c.type==cLADDERHOOKSHOT && isstepable(cmbdat) && ishookshottable(xx,yy))
4019 {
4020 for(int32_t k=0; k<8; k+=2)
4021 for(int32_t j=0; j<8; j+=2)
4022 rectfill(dest,tx+k,ty+j,tx+k+1,ty+j+1,((k+j)/2)%2 ? makecol(165,105,8) : makecol(170,170,170));
4023 }
4024 else
4025 {
4026 int32_t color = makecol(178,36,36);
4027
4028 if(isstepable(cmbdat)&& (!doladdercheck))
4029 color=makecol(165,105,8);
4030 else if((c.type==cHOOKSHOTONLY || c.type==cLADDERHOOKSHOT) && ishookshottable(xx,yy))
4031 color=makecol(170,170,170);
4032
4033 rectfill(dest,tx,ty,tx+7,ty+7,color);
4034 }
4035 }
4036 }
4037
4038 // Draw damage combos
4039 bool dmg = combo_class_buf[combobuf[MAPCOMBO2(-1,xx,yy)].type].modify_hp_amount
4040 || combo_class_buf[combobuf[MAPCOMBO2(0,xx,yy)].type].modify_hp_amount
4041 || combo_class_buf[combobuf[MAPCOMBO2(1,xx,yy)].type].modify_hp_amount;
4042
4043 if(dmg)
4044 {
4045 int32_t color = makecol(255,255,0);
4046 if (bridgedetected <= 0)
4047 {
4048 for(int32_t k=0; k<16; k+=2)
4049 for(int32_t j=0; j<16; j+=2)
4050 if(((k+j)/2)%2)
4051 {
4052 int32_t x0 = x - viewport.x;
4053 int32_t y0 = y - viewport.y;
4054 rectfill(dest,x0+k,y0+j,x0+k+1,y0+j+1,color);
4055 }
4056 }
4057 else
4058 {
4059 for(int32_t i=0; i<4; i++)
4060 {
4061 if (!(bridgedetected & (1<<i)))
4062 {
4063 int32_t tx=((i&2)<<2)+x - viewport.x;
4064 int32_t ty=((i&1)<<3)+y - viewport.y;
4065 for(int32_t k=0; k<8; k+=2)
4066 for(int32_t j=0; j<8; j+=2)
4067 if((k+j)%4 < 2) rectfill(dest,tx+k,ty+j,tx+k+1,ty+j+1,color);
4068 }
4069 }
4070 }
4071 }
4072 }
4073 static void put_walkflags_a5(int32_t x, int32_t y, word cmbdat, int32_t lyr)
4074 {
4075 ALLEGRO_COLOR col_solid = al_map_rgba(178,36,36,info_opacity);
4076 ALLEGRO_COLOR col_water1 = al_map_rgba(85,85,255,info_opacity);
4077 ALLEGRO_COLOR col_lhook = al_map_rgba(170,170,170,info_opacity);
4078 ALLEGRO_COLOR col_stepable = al_map_rgba(165,105,8,info_opacity);
4079 ALLEGRO_COLOR col_dmg = al_map_rgba(255,255,0,info_opacity);
4080 newcombo const &c = combobuf[cmbdat];
4081
4082 if (c.type == cBRIDGE && get_qr(qr_OLD_BRIDGE_COMBOS)) return;
4083
4084 int32_t xx = x-viewport.x;
4085 int32_t yy = y+playing_field_offset-viewport.y;
4086
4087 int32_t bridgedetected = 0;
4088
4089 // Draw damage combos
4090 bool dmg = combo_class_buf[c.type].modify_hp_amount;
4091
4092 for(int32_t i=0; i<4; i++)
4093 {
4094 int32_t tx=((i&2)<<2)+xx;
4095 int32_t ty=((i&1)<<3)+yy;
4096 int32_t tx2=((i&2)<<2)+x;
4097 int32_t ty2=((i&1)<<3)+y;
4098 for (int32_t m = lyr-1; m <= 1; m++)
4099 {
4100 if (get_qr(qr_OLD_BRIDGE_COMBOS))
4101 {
4102 if (m >= 0 && combobuf[MAPCOMBO2(m, tx2, ty2)].type == cBRIDGE && !_walkflag_layer(tx2, ty2, m))
4103 {
4104 bridgedetected |= (1<<i);
4105 }
4106 }
4107 else
4108 {
4109 if (m >= 0 && combobuf[MAPCOMBO2(m, tx2, ty2)].type == cBRIDGE && _effectflag_layer(tx2, ty2, m))
4110 {
4111 bridgedetected |= (1<<i);
4112 }
4113 }
4114 }
4115 if ((bridgedetected & (1<<i)))
4116 continue;
4117 bool doladdercheck = true;
4118
4119 if ((c.walk&(1<<(i+4))) && ((c.walk&(1<<i) && ((c.usrflags&cflag4)) && c.type == cWATER) || c.type == cSHALLOWWATER))
4120 {
4121 for(int32_t k=0; k<8; k+=2)
4122 for(int32_t j=0; j<8; j+=2)
4123 if(((k+j)/2)%2)
4124 al_draw_filled_rectangle(tx+k,ty+j,tx+k+2,ty+j+2,col_water1);
4125 }
4126 if (iswater_type(c.type) && !DRIEDLAKE && !((c.walk&(1<<(i+4))) && ((c.walk&(1<<i) && ((c.usrflags&cflag3) || (c.usrflags&cflag4)) && c.type == cWATER)))) //Yes, I realize this is horribly inaccurate; the alternative is the game chugging every time you turn on walk cheats.
4127 {
4128 if (get_qr(qr_NO_SOLID_SWIM)) doladdercheck = false;
4129 if((lyr==0 || (get_qr(qr_WATER_ON_LAYER_1) && lyr == 1) || (get_qr(qr_WATER_ON_LAYER_2) && lyr == 2)) && get_qr(qr_DROWN))
4130 al_draw_filled_rectangle(tx,ty,tx+8,ty+8,col_water1);
4131 else al_draw_filled_rectangle(tx,ty,tx+8,ty+8,col_lhook);
4132 }
4133
4134 if(c.walk&(1<<i) && !(iswater_type(c.type) && DRIEDLAKE) && !((c.walk&(1<<(i+4))) && ((c.walk&(1<<i) && ((c.usrflags&cflag3) || (c.usrflags&cflag4)) && c.type == cWATER)))) // Check for dried lake (watertype && not water)
4135 {
4136 if(c.type==cLADDERHOOKSHOT && isstepable(cmbdat) && ishookshottable(xx,yy))
4137 {
4138 for(int32_t k=0; k<8; k+=2)
4139 for(int32_t j=0; j<8; j+=2)
4140 al_draw_filled_rectangle(tx+k,ty+j,tx+k+2,ty+j+2,((k+j)/2)%2 ? col_stepable : col_lhook);
4141 }
4142 else
4143 {
4144 ALLEGRO_COLOR* color = &col_solid;
4145
4146 if(isstepable(cmbdat)&& (!doladdercheck))
4147 color=&col_stepable;
4148 else if((c.type==cHOOKSHOTONLY || c.type==cLADDERHOOKSHOT) && ishookshottable(xx,yy))
4149 color=&col_lhook;
4150
4151 al_draw_filled_rectangle(tx,ty,tx+8,ty+8,*color);
4152 }
4153 }
4154
4155 if(dmg)
4156 {
4157 for(int32_t k=0; k<8; k+=2)
4158 for(int32_t j=0; j<8; j+=2)
4159 if((k+j)%4 < 2) al_draw_filled_rectangle(tx+k,ty+j,tx+k+2,ty+j+2,col_dmg);
4160 }
4161 }
4162 }
4163
4164 void put_effectflags(BITMAP *dest,int32_t x,int32_t y,int32_t xofs,int32_t yofs, word cmbdat,int32_t lyr)
4165 {
4166 newcombo const &c = combobuf[cmbdat];
4167
4168 int32_t xx = x-xofs-viewport.x;
4169 int32_t yy = y+playing_field_offset-yofs-viewport.y;
4170
4171 for(int32_t i=0; i<4; i++)
4172 {
4173 int32_t tx=((i&2)<<2)+xx;
4174 int32_t ty=((i&1)<<3)+yy;
4175
4176 if(((c.walk>>4)&(1<<i)) && c.type != cNONE)
4177 {
4178 int32_t color = vc(10);
4179
4180 rectfill(dest,tx,ty,tx+7,ty+7,color);
4181 }
4182 }
4183 }
4184 static void put_effectflags_a5(int32_t x, int32_t y, word cmbdat, int32_t lyr)
4185 {
4186 ALLEGRO_COLOR col_eff = al_map_rgba(85,255,85,info_opacity);
4187 newcombo const &c = combobuf[cmbdat];
4188
4189 int32_t xx = x-viewport.x;
4190 int32_t yy = y+playing_field_offset-viewport.y;
4191
4192 for(int32_t i=0; i<4; i++)
4193 {
4194 int32_t tx=((i&2)<<2)+xx;
4195 int32_t ty=((i&1)<<3)+yy;
4196
4197 if(((c.walk>>4)&(1<<i)) && c.type != cNONE)
4198 {
4199 al_draw_filled_rectangle(tx,ty,tx+8,ty+8,col_eff);
4200 }
4201 }
4202 }
4203
4204 void draw_ladder_platform(BITMAP* dest, int32_t x, int32_t y, int32_t c)
4205 {
4206 for(auto cx = 0; cx < 256; cx += 16)
4207 {
4208 for(auto cy = 0; cy < 176; cy += 16)
4209 {
4210 if(isSVLadder(cx,cy))
4211 {
4212 auto nx = cx+x, ny = cy+y;
4213 if(cy && !isSVLadder(cx,cy-16))
4214 line(dest,nx,ny,nx+15,ny,c);
4215 rectfill(dest,nx,ny,nx+3,ny+15,c);
4216 rectfill(dest,nx+12,ny,nx+15,ny+15,c);
4217 rectfill(dest,nx+4,ny+2,nx+11,ny+5,c);
4218 rectfill(dest,nx+4,ny+10,nx+11,ny+13,c);
4219 }
4220 else if(isSVPlatform(cx,cy))
4221 {
4222 line(dest,cx+x,cy+y,cx+x+15,cy+y,c);
4223 }
4224 }
4225 }
4226 }
4227 void draw_ladder_platform_a5(int32_t x, int32_t y, ALLEGRO_COLOR c)
4228 {
4229 for(auto cx = 0; cx < 256; cx += 16)
4230 {
4231 for(auto cy = 0; cy < 176; cy += 16)
4232 {
4233 if(isSVLadder(cx,cy))
4234 {
4235 auto nx = cx+x, ny = cy+y;
4236 if(cy && !isSVLadder(cx,cy-16))
4237 al_draw_line(nx,ny,nx+15,ny,c,1);
4238 al_draw_filled_rectangle(nx,ny,nx+4,ny+16,c);
4239 al_draw_filled_rectangle(nx+12,ny,nx+16,ny+16,c);
4240 al_draw_filled_rectangle(nx+4,ny+2,nx+12,ny+6,c);
4241 al_draw_filled_rectangle(nx+4,ny+10,nx+12,ny+14,c);
4242 }
4243 else if(isSVPlatform(cx,cy))
4244 {
4245 al_draw_line(cx+x,cy+y,cx+x+15,cy+y,c,1);
4246 }
4247 }
4248 }
4249 }
4250
4251 // Walkflags L4 cheat
4252 void do_walkflags(const screen_handles_t& screen_handles, int32_t x, int32_t y)
4253 {
4254 if (!show_walkflags)
4255 return;
4256
4257 start_info_bmp();
4258
4259 mapscr* scr = screen_handles[0].scr;
4260 for(int32_t i=0; i<176; i++)
4261 {
4262 put_walkflags_a5(((i&15)<<4) + x, (i&0xF0) + y, scr->data[i], 0);
4263 }
4264
4265 for(int32_t k=0; k<2; k++)
4266 {
4267 scr = screen_handles[k + 1].scr;
4268
4269 if (scr)
4270 {
4271 for(int32_t i=0; i<176; i++)
4272 {
4273 put_walkflags_a5(((i&15)<<4) + x, (i&0xF0) + y, scr->data[i], k%2+1);
4274 }
4275 }
4276 }
4277
4278 end_info_bmp();
4279 }
4280
4281 void do_walkflags(int32_t x, int32_t y)
4282 {
4283 if (!show_walkflags)
4284 return;
4285
4286 x += -viewport.x;
4287 y += playing_field_offset - viewport.y;
4288
4289 start_info_bmp();
4290
4291 draw_ladder_platform_a5(x,y,al_map_rgba(165,105,8,info_opacity));
4292 draw_solid_objects_a5(x,y,al_map_rgba(178,36,36,info_opacity));
4293 draw_slopes_a5(x,y,al_map_rgba(255,85,255,info_opacity));
4294
4295 end_info_bmp();
4296 }
4297
4298 // Effectflags L4 cheat
4299 void do_effectflags(mapscr* scr, int32_t x, int32_t y)
4300 {
4301 if(show_effectflags)
4302 {
4303 start_info_bmp();
4304
4305 for(int32_t i=0; i<176; i++)
4306 {
4307 put_effectflags_a5(((i&15)<<4) + x, (i&0xF0) + y, scr->data[i], 0);
4308 }
4309
4310 end_info_bmp();
4311 }
4312 }
4313
4314 400489 void calc_darkroom_combos(mapscr* scr, int offx, int offy)
4315 {
4316 400489 int map = scr->map;
4317 400489 int screen = scr->screen;
4318
4319
2/2
✓ Branch 0 taken 2803423 times.
✓ Branch 1 taken 400489 times.
3203912 for(int32_t lyr = 0; lyr < 7; ++lyr)
4320 {
4321 2803423 mapscr* scr = get_scr_layer(map, screen, lyr);
4322
2/2
✓ Branch 0 taken 1829718 times.
✓ Branch 1 taken 973705 times.
2803423 if (!scr->is_valid()) continue;
4323
4324
2/2
✓ Branch 0 taken 322030368 times.
✓ Branch 1 taken 1829718 times.
323860086 for(int32_t q = 0; q < 176; ++q)
4325 {
4326 322030368 newcombo const& cmb = combobuf[scr->data[q]];
4327
2/2
✓ Branch 0 taken 320498295 times.
✓ Branch 1 taken 1532073 times.
322030368 if(cmb.type == cTORCH)
4328 {
4329 1532073 do_torch_combo(cmb, COMBOX(q)+8+offx, COMBOY(q)+8+offy, darkscr_bmp);
4330 1532073 }
4331 322030368 }
4332 1829718 }
4333 400489 }
4334
4335 400489 void calc_darkroom_ffcs(mapscr* scr, int offx, int offy)
4336 {
4337 400489 word c = scr->numFFC();
4338
2/2
✓ Branch 0 taken 704965 times.
✓ Branch 1 taken 400489 times.
1105454 for(int q = 0; q < c; ++q)
4339 {
4340 704965 newcombo const& cmb = combobuf[scr->ffcs[q].data];
4341
2/2
✓ Branch 0 taken 690157 times.
✓ Branch 1 taken 14808 times.
704965 if(cmb.type == cTORCH)
4342 {
4343 14808 int cx = scr->ffcs[q].x.getInt()+(scr->ffEffectWidth(q)/2)+offx;
4344 14808 int cy = (scr->ffcs[q].y.getInt())+(scr->ffEffectHeight(q)/2)+offy;
4345 14808 do_torch_combo(cmb, cx, cy, darkscr_bmp);
4346 14808 }
4347 704965 }
4348 400489 }
4349
4350 struct nearby_screen_t
4351 {
4352 int screen;
4353 int offx;
4354 int offy;
4355 screen_handles_t screen_handles;
4356 };
4357 typedef std::vector<nearby_screen_t> nearby_screens_t;
4358
4359 16077826 static nearby_screens_t get_nearby_screens_non_scrolling_region()
4360 {
4361 16077826 nearby_screens_t nearby_screens;
4362
4363 16077826 mapscr* base_scr = origin_scr;
4364
1/2
✓ Branch 0 taken 16077826 times.
✗ Branch 1 not taken.
16077826 auto& nearby_screen = nearby_screens.emplace_back();
4365 16077826 nearby_screen.screen = cur_screen;
4366
1/2
✓ Branch 0 taken 16077826 times.
✗ Branch 1 not taken.
16077826 nearby_screen.screen_handles = create_screen_handles(base_scr);
4367
4368 16077826 return nearby_screens;
4369
1/2
✓ Branch 0 taken 16077826 times.
✗ Branch 1 not taken.
16077826 }
4370
4371 48296 static nearby_screens_t get_nearby_screens_scrolling_region()
4372 {
4373 48296 nearby_screens_t nearby_screens;
4374
4375
1/2
✓ Branch 0 taken 48296 times.
✗ Branch 1 not taken.
48296 int screens_x0 = viewport.left() / 256;
4376
1/2
✓ Branch 0 taken 48296 times.
✗ Branch 1 not taken.
48296 int screens_x1 = (viewport.right() - 1) / 256;
4377
1/2
✓ Branch 0 taken 48296 times.
✗ Branch 1 not taken.
48296 int screens_y0 = viewport.top() / 176;
4378
1/2
✓ Branch 0 taken 48296 times.
✗ Branch 1 not taken.
48296 int screens_y1 = (viewport.bottom() - 1) / 176;
4379
4380
1/2
✓ Branch 0 taken 48296 times.
✗ Branch 1 not taken.
48296 screens_x0 = std::clamp(screens_x0, 0, 15);
4381
1/2
✓ Branch 0 taken 48296 times.
✗ Branch 1 not taken.
48296 screens_x1 = std::clamp(screens_x1, 0, 15);
4382
1/2
✓ Branch 0 taken 48296 times.
✗ Branch 1 not taken.
48296 screens_y0 = std::clamp(screens_y0, 0, 8);
4383
1/2
✓ Branch 0 taken 48296 times.
✗ Branch 1 not taken.
48296 screens_y1 = std::clamp(screens_y1, 0, 8);
4384
4385
2/2
✓ Branch 0 taken 48296 times.
✓ Branch 1 taken 79928 times.
128224 for (int x = screens_x0; x <= screens_x1; x++)
4386 {
4387
2/2
✓ Branch 0 taken 169672 times.
✓ Branch 1 taken 79928 times.
249600 for (int y = screens_y0; y <= screens_y1; y++)
4388 {
4389 169672 int screen = cur_screen + x + y*16;
4390
1/2
✓ Branch 0 taken 169672 times.
✗ Branch 1 not taken.
169672 if (!is_in_current_region(screen)) continue;
4391
4392
1/2
✓ Branch 0 taken 169672 times.
✗ Branch 1 not taken.
169672 mapscr* base_scr = get_scr(screen);
4393
1/2
✓ Branch 0 taken 169672 times.
✗ Branch 1 not taken.
169672 if (!base_scr->is_valid()) continue;
4394
4395
1/2
✓ Branch 0 taken 169672 times.
✗ Branch 1 not taken.
169672 auto [offx, offy] = translate_screen_coordinates_to_world(screen);
4396
4397
1/2
✓ Branch 0 taken 169672 times.
✗ Branch 1 not taken.
169672 auto& nearby_screen = nearby_screens.emplace_back();
4398 169672 nearby_screen.screen = screen;
4399 169672 nearby_screen.offx = offx;
4400 169672 nearby_screen.offy = offy;
4401
1/2
✓ Branch 0 taken 169672 times.
✗ Branch 1 not taken.
169672 nearby_screen.screen_handles = create_screen_handles(base_scr);
4402 169672 }
4403 79928 }
4404
4405 48296 return nearby_screens;
4406
1/2
✓ Branch 0 taken 48296 times.
✗ Branch 1 not taken.
48296 }
4407
4408 3658 static nearby_screens_t get_nearby_screens_smooth_maze()
4409 {
4410 3658 nearby_screens_t nearby_screens;
4411
4412
1/2
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
3658 int screens_x0 = viewport.left() / 256;
4413
1/2
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
3658 int screens_x1 = (viewport.right() - 1) / 256;
4414
1/2
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
3658 int screens_y0 = viewport.top() / 176;
4415
1/2
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
3658 int screens_y1 = (viewport.bottom() - 1) / 176;
4416
4417
2/4
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3658 times.
✗ Branch 3 not taken.
3658 if (viewport.left() < 0) screens_x0--;
4418
2/4
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3658 times.
✗ Branch 3 not taken.
3658 if (viewport.top() < 0) screens_y0--;
4419
4420
2/2
✓ Branch 0 taken 3658 times.
✓ Branch 1 taken 7308 times.
10966 for (int x = screens_x0; x <= screens_x1; x++)
4421 {
4422
2/2
✓ Branch 0 taken 18600 times.
✓ Branch 1 taken 7308 times.
25908 for (int y = screens_y0; y <= screens_y1; y++)
4423 {
4424 18600 int screen = -1;
4425 mapscr* base_scr;
4426 int offx, offy;
4427
4428 18600 mapscr* maze_scr = maze_state.scr;
4429 18600 int maze_screen = maze_scr->screen;
4430
1/2
✓ Branch 0 taken 18600 times.
✗ Branch 1 not taken.
18600 int maze_screen_x = get_region_relative_dx(maze_screen);
4431
1/2
✓ Branch 0 taken 18600 times.
✗ Branch 1 not taken.
18600 int maze_screen_y = get_region_relative_dy(maze_screen);
4432 18600 int maze_screen_dx = x - maze_screen_x;
4433 18600 int maze_screen_dy = y - maze_screen_y;
4434 18600 int exitdir = maze_scr->exitdir;
4435
4436 bool should_draw_maze_screen;
4437
2/2
✓ Branch 0 taken 9052 times.
✓ Branch 1 taken 9548 times.
18600 if (maze_state.lost)
4438 {
4439 9548 should_draw_maze_screen = true;
4440 9548 }
4441 else
4442 {
4443 9052 should_draw_maze_screen = true;
4444
4/6
✓ Branch 0 taken 9052 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 6844 times.
✓ Branch 3 taken 2208 times.
✓ Branch 4 taken 6844 times.
✗ Branch 5 not taken.
9052 should_draw_maze_screen &= XY_DELTA_TO_DIR(maze_screen_dx, 0) != exitdir && XY_DELTA_TO_DIR(0, maze_screen_dy) != exitdir;
4445
2/2
✓ Branch 0 taken 3850 times.
✓ Branch 1 taken 5202 times.
9052 if (maze_state.enter_dir != dir_invalid)
4446
4/6
✓ Branch 0 taken 3850 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3304 times.
✓ Branch 3 taken 546 times.
✓ Branch 4 taken 3304 times.
✗ Branch 5 not taken.
3850 should_draw_maze_screen &= XY_DELTA_TO_DIR(maze_screen_dx, 0) != maze_state.enter_dir && XY_DELTA_TO_DIR(0, maze_screen_dy) != maze_state.enter_dir;
4447 }
4448
4449
2/2
✓ Branch 0 taken 16048 times.
✓ Branch 1 taken 2552 times.
18600 if (should_draw_maze_screen)
4450 {
4451 16048 screen = maze_state.scr->screen;
4452 16048 base_scr = maze_state.scr;
4453
1/2
✓ Branch 0 taken 16048 times.
✗ Branch 1 not taken.
16048 std::tie(offx, offy) = translate_screen_coordinates_to_world(cur_screen + x + y*16);
4454 16048 }
4455
4456
2/2
✓ Branch 0 taken 16048 times.
✓ Branch 1 taken 2552 times.
18600 if (screen == -1)
4457 {
4458 2552 screen = cur_screen + x + y*16;
4459
1/2
✓ Branch 0 taken 2552 times.
✗ Branch 1 not taken.
2552 if (!is_in_current_region(screen)) continue;
4460
4461
1/2
✓ Branch 0 taken 2552 times.
✗ Branch 1 not taken.
2552 base_scr = get_scr(screen);
4462
1/2
✓ Branch 0 taken 2552 times.
✗ Branch 1 not taken.
2552 if (!base_scr->is_valid()) continue;
4463
4464
1/2
✓ Branch 0 taken 2552 times.
✗ Branch 1 not taken.
2552 std::tie(offx, offy) = translate_screen_coordinates_to_world(screen);
4465 2552 }
4466
4467
1/2
✓ Branch 0 taken 18600 times.
✗ Branch 1 not taken.
18600 auto& nearby_screen = nearby_screens.emplace_back();
4468 18600 nearby_screen.screen = screen;
4469 18600 nearby_screen.offx = offx;
4470 18600 nearby_screen.offy = offy;
4471
1/2
✓ Branch 0 taken 18600 times.
✗ Branch 1 not taken.
18600 nearby_screen.screen_handles = create_screen_handles(base_scr);
4472 18600 }
4473 7308 }
4474
4475 3658 return nearby_screens;
4476
1/2
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
3658 }
4477
4478 16129780 static nearby_screens_t get_nearby_screens()
4479 {
4480
4/4
✓ Branch 0 taken 9214 times.
✓ Branch 1 taken 16120566 times.
✓ Branch 2 taken 3658 times.
✓ Branch 3 taken 5556 times.
16129780 if (maze_state.active && maze_state.loopy)
4481 3658 return get_nearby_screens_smooth_maze();
4482
4483
2/2
✓ Branch 0 taken 48296 times.
✓ Branch 1 taken 16077826 times.
16126122 if (is_in_scrolling_region())
4484 48296 return get_nearby_screens_scrolling_region();
4485
4486 16077826 return get_nearby_screens_non_scrolling_region();
4487 16129780 }
4488
4489 209914889 static void for_every_nearby_screen(const nearby_screens_t& nearby_screens, const std::function <void (screen_handles_t, int, int, int)>& fn)
4490 {
4491
2/2
✓ Branch 0 taken 211699491 times.
✓ Branch 1 taken 209914889 times.
421614380 for (auto& nearby_screen : nearby_screens)
4492 211699491 fn(nearby_screen.screen_handles, nearby_screen.screen, nearby_screen.offx, nearby_screen.offy);
4493 209914889 }
4494
4495 145252532 static void draw_msgstr(byte layer, BITMAP* dest = nullptr)
4496 {
4497
2/2
✓ Branch 0 taken 32301054 times.
✓ Branch 1 taken 112951478 times.
145252532 if(layer != msgstr_layer) return;
4498
2/2
✓ Branch 0 taken 16129018 times.
✓ Branch 1 taken 16172036 times.
32301054 if(!dest) dest = framebuf;
4499
4500
2/2
✓ Branch 0 taken 1456511 times.
✓ Branch 1 taken 30844543 times.
32301054 if(!(msg_bg_display_buf->clip))
4501 {
4502 1456511 blit_msgstr_bg(dest,0,0,0,playing_field_offset,256,176);
4503 1456511 }
4504
4505
2/2
✓ Branch 0 taken 1456511 times.
✓ Branch 1 taken 30844543 times.
32301054 if(!(msg_portrait_display_buf->clip))
4506 {
4507 1456511 blit_msgstr_prt(dest,0,0,0,playing_field_offset,256,176);
4508 1456511 }
4509
4510
2/2
✓ Branch 0 taken 1483325 times.
✓ Branch 1 taken 30817729 times.
32301054 if(!(msg_txt_display_buf->clip))
4511 {
4512 1483325 blit_msgstr_fg(dest,0,0,0,playing_field_offset,256,176);
4513 1483325 }
4514 145252532 }
4515
4516 static void putscrdoors(const nearby_screens_t& nearby_screens, BITMAP *dest, int32_t x, int32_t y);
4517
4518 64519120 static void set_draw_screen_clip(BITMAP* bmp)
4519 {
4520 64519120 set_clip_rect(bmp, draw_screen_clip_rect_x1, draw_screen_clip_rect_y1, draw_screen_clip_rect_x2, draw_screen_clip_rect_y2);
4521 64519120 }
4522
4523 17580 static void draw_sprites(BITMAP* dest, set<sprite*, SpriteSorter>& sprite_set, set<sprite*, SpriteSorter>::iterator& it, word upto_z)
4524 {
4525 17580 bool checkz = upto_z != word(-1); // max value represents "infinity" height
4526
6/6
✓ Branch 0 taken 11145 times.
✓ Branch 1 taken 6435 times.
✓ Branch 2 taken 160 times.
✓ Branch 3 taken 6275 times.
✓ Branch 4 taken 12905 times.
✓ Branch 5 taken 4675 times.
17580 if(it == sprite_set.end() || (checkz && (*it)->total_z() >= upto_z))
4527 12905 return; // no sprites to draw remaining
4528 // Just clips sprites if in a repeating, smooth maze.
4529
1/2
✓ Branch 0 taken 4675 times.
✗ Branch 1 not taken.
4675 bool do_clip = maze_state.active && maze_state.loopy;
4530
4531
4532
1/2
✓ Branch 0 taken 4675 times.
✗ Branch 1 not taken.
4675 if(do_clip)
4533 {
4534 int maze_screen = maze_state.scr->screen;
4535 auto [sx, sy] = translate_screen_coordinates_to_world(maze_screen);
4536 set_clip_rect(dest, sx - viewport.x, sy - viewport.y, sx + 256 - viewport.x, sy + 176 - viewport.y);
4537 }
4538
6/6
✓ Branch 0 taken 2930 times.
✓ Branch 1 taken 32443 times.
✓ Branch 2 taken 160 times.
✓ Branch 3 taken 32283 times.
✓ Branch 4 taken 4675 times.
✓ Branch 5 taken 30698 times.
67816 while(it != sprite_set.end() && (!checkz || (*it)->total_z() < upto_z))
4539 {
4540 30698 sprite* spr = *it;
4541
2/2
✓ Branch 0 taken 27768 times.
✓ Branch 1 taken 2930 times.
30698 if(spr == &Hero) // Draw the Hero
4542 {
4543 2930 decorations.draw2(dest,true);
4544 2930 Hero.draw(dest);
4545 2930 decorations.draw(dest,true);
4546
4547 // Draw enemies holding the Hero directly above the Hero
4548
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2930 times.
2930 for(int32_t i=0; i<guys.Count(); i++)
4549 {
4550 if(((enemy*)guys.spr(i))->type == eeWALK)
4551 if(((eStalfos*)guys.spr(i))->hashero)
4552 guys.spr(i)->draw(dest);
4553 else if(((enemy*)guys.spr(i))->type == eeWALLM)
4554 if(((eWallM*)guys.spr(i))->hashero)
4555 guys.spr(i)->draw(dest);
4556 }
4557 2930 }
4558
2/2
✓ Branch 0 taken 24838 times.
✓ Branch 1 taken 2930 times.
27768 else if(spr == &mblock2) // Draw the moving pushblock
4559 {
4560 2930 mblock2.draw(dest, -1);
4561 2930 do_primitives(dest, SPLAYER_MOVINGBLOCK);
4562 2930 }
4563
2/4
✓ Branch 0 taken 24838 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 24838 times.
24838 else if(enemy* e = dynamic_cast<enemy*>(spr))
4564 {
4565 e->draw(dest);
4566 e->draw2(dest); // used specifically for eGleeok/esGleeok
4567 }
4568 24838 else spr->draw(dest);
4569 30698 ++it;
4570 }
4571
1/2
✓ Branch 0 taken 4675 times.
✗ Branch 1 not taken.
4675 if(do_clip)
4572 clear_clip_rect(dest);
4573 17580 }
4574
4575 11991 static void draw_high_darkness(BITMAP* dest)
4576 {
4577 11991 do_primitives(dest, SPLAYER_DARKROOM_UNDER);
4578 11991 set_clip_rect(dest, 0, playing_field_offset, dest->w, dest->h);
4579
1/2
✓ Branch 0 taken 11991 times.
✗ Branch 1 not taken.
11991 if(hero_scr->flags9 & fDARK_DITHER) //dither the entire bitmap
4580 {
4581 ditherblit(darkscr_bmp,darkscr_bmp,0,game->get_dither_type(),game->get_dither_arg());
4582 ditherblit(darkscr_bmp_trans,darkscr_bmp_trans,0,game->get_dither_type(),game->get_dither_arg());
4583 }
4584
4585 11991 color_map = &trans_table2;
4586
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 11991 times.
11991 if(hero_scr->flags9 & fDARK_TRANS) //draw the dark as transparent
4587 {
4588 draw_trans_sprite(dest, darkscr_bmp, 0, 0);
4589 if(get_qr(qr_NEWDARK_TRANS_STACKING))
4590 draw_trans_sprite(dest, darkscr_bmp_trans, 0, 0);
4591 }
4592 else
4593 {
4594 11991 masked_blit(darkscr_bmp, dest, 0, 0, 0, 0, dest->w, dest->h);
4595 11991 draw_trans_sprite(dest, darkscr_bmp_trans, 0, 0);
4596 }
4597 11991 color_map = &trans_table;
4598
4599 11991 set_clip_rect(dest, 0, 0, dest->w, dest->h);
4600 11991 do_primitives(dest, SPLAYER_DARKROOM_OVER);
4601 11991 }
4602
4603 16172036 static void draw_screen_post_passive_subscreen(BITMAP* dest, bool any_dark)
4604 {
4605 16172036 draw_msgstr(6, dest);
4606
4607
1/2
✓ Branch 0 taken 16172036 times.
✗ Branch 1 not taken.
16172036 if (get_qr(qr_LAYER6_STRINGS_OVER_SUBSCREEN))
4608 draw_msgstr(6, dest);
4609
4610
6/6
✓ Branch 0 taken 1901823 times.
✓ Branch 1 taken 14270213 times.
✓ Branch 2 taken 450140 times.
✓ Branch 3 taken 1451683 times.
✓ Branch 4 taken 438149 times.
✓ Branch 5 taken 11991 times.
16172036 if (get_qr(qr_NEW_DARKROOM) && !get_qr(qr_NEWDARK_L6) && any_dark)
4611 11991 draw_high_darkness(dest);
4612
4613 16172036 _do_current_ffc_layer(dest, 7);
4614 16172036 draw_msgstr(7, dest);
4615 16172036 }
4616
4617 // Draws to framebuf.
4618 //
4619 // But if drawPassiveSubscreenSeparate is true: framebuf_no_passive_subscreen will also contain all
4620 // draws excluding the passive subscreen.
4621 16129780 void draw_screen(bool showhero, bool runGeneric, bool drawPassiveSubscreenSeparate)
4622 {
4623 16129780 bool classic_draw = get_qr(qr_CLASSIC_DRAWING_ORDER);
4624 16129780 clear_info_bmp();
4625
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16129780 times.
16129780 if((GameFlags & (GAMEFLAG_SCRIPTMENU_ACTIVE|GAMEFLAG_F6SCRIPT_ACTIVE))!=0)
4626 {
4627 FFCore.doScriptMenuDraws();
4628 return;
4629 }
4630
4631
2/2
✓ Branch 0 taken 613571 times.
✓ Branch 1 taken 15516209 times.
16129780 if(runGeneric) FFCore.runGenericPassiveEngine(SCR_TIMING_PRE_DRAW);
4632
4633 16129780 BITMAP* dest = framebuf;
4634 16129780 clear_bitmap(dest);
4635 16129780 clear_clip_rect(dest);
4636
4637 16129780 int32_t cmby2=0;
4638
4639 // Draw some background layers
4640 16129780 clear_bitmap(scrollbuf);
4641
4642 16129780 auto nearby_screens = get_nearby_screens();
4643
4644
2/2
✓ Branch 0 taken 16126850 times.
✓ Branch 1 taken 2930 times.
16129780 if (!classic_draw)
4645 {
4646
2/2
✓ Branch 0 taken 11720 times.
✓ Branch 1 taken 2930 times.
14650 for (int layer = -7; layer <= -4; ++layer)
4647 {
4648
1/2
✓ Branch 0 taken 11720 times.
✗ Branch 1 not taken.
11720 _do_current_ffc_layer(scrollbuf, layer);
4649
2/4
✓ Branch 0 taken 11720 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 11720 times.
11720 if (script_drawing_commands.is_dirty(layer))
4650 do_primitives(scrollbuf, layer);
4651 11720 }
4652 2930 }
4653
4654 // Handle layer 2/3 possibly being background layers.
4655
2/2
✓ Branch 0 taken 2930 times.
✓ Branch 1 taken 16126850 times.
16129780 if (classic_draw) // weird ordering (-3 > -2)
4656 {
4657
1/2
✓ Branch 0 taken 16126850 times.
✗ Branch 1 not taken.
32390018 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
4658 16263168 mapscr* base_scr = screen_handles[0].base_scr;
4659
2/2
✓ Branch 0 taken 16121047 times.
✓ Branch 1 taken 142121 times.
16263168 if (XOR(base_scr->flags7&fLAYER2BG, DMaps[cur_dmap].flags&dmfLAYER2BG))
4660 142121 do_layer(scrollbuf, 0, screen_handles[2], offx, offy);
4661 16263168 });
4662
4663 16126850 bool l2bg = XOR(origin_scr->flags7&fLAYER2BG, DMaps[cur_dmap].flags&dmfLAYER2BG);
4664
2/2
✓ Branch 0 taken 142121 times.
✓ Branch 1 taken 15984729 times.
16126850 if (l2bg)
4665 {
4666
1/2
✓ Branch 0 taken 142121 times.
✗ Branch 1 not taken.
142121 do_layer_primitives(scrollbuf, 2);
4667
1/2
✓ Branch 0 taken 142121 times.
✗ Branch 1 not taken.
142121 particles.draw(scrollbuf, true, 2);
4668 142121 }
4669
1/2
✓ Branch 0 taken 16126850 times.
✗ Branch 1 not taken.
16126850 _do_current_ffc_layer(scrollbuf, -2);
4670
2/2
✓ Branch 0 taken 142121 times.
✓ Branch 1 taken 15984729 times.
16126850 if (l2bg)
4671
1/2
✓ Branch 0 taken 142121 times.
✗ Branch 1 not taken.
142121 draw_msgstr(2, scrollbuf);
4672 16126850 }
4673
4674
1/2
✓ Branch 0 taken 16129780 times.
✗ Branch 1 not taken.
32395878 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
4675 16266098 mapscr* base_scr = screen_handles[0].base_scr;
4676
2/2
✓ Branch 0 taken 16031534 times.
✓ Branch 1 taken 234564 times.
16266098 if (XOR(base_scr->flags7&fLAYER3BG, DMaps[cur_dmap].flags&dmfLAYER3BG))
4677 234564 do_layer(scrollbuf, 0, screen_handles[3], offx, offy);
4678 16266098 });
4679
4680
2/2
✓ Branch 0 taken 234564 times.
✓ Branch 1 taken 15895216 times.
16129780 if (XOR(origin_scr->flags7&fLAYER3BG, DMaps[cur_dmap].flags&dmfLAYER3BG))
4681 {
4682
1/2
✓ Branch 0 taken 234564 times.
✗ Branch 1 not taken.
234564 do_layer_primitives(scrollbuf, 3);
4683
1/2
✓ Branch 0 taken 234564 times.
✗ Branch 1 not taken.
234564 particles.draw(scrollbuf, true, 3);
4684 234564 }
4685
1/2
✓ Branch 0 taken 16129780 times.
✗ Branch 1 not taken.
16129780 _do_current_ffc_layer(scrollbuf, -3);
4686
2/2
✓ Branch 0 taken 234564 times.
✓ Branch 1 taken 15895216 times.
16129780 if (XOR(origin_scr->flags7&fLAYER3BG, DMaps[cur_dmap].flags&dmfLAYER3BG))
4687
1/2
✓ Branch 0 taken 234564 times.
✗ Branch 1 not taken.
234564 draw_msgstr(3, scrollbuf);
4688
4689
2/2
✓ Branch 0 taken 2930 times.
✓ Branch 1 taken 16126850 times.
16129780 if (!classic_draw)
4690 {
4691
1/2
✓ Branch 0 taken 2930 times.
✗ Branch 1 not taken.
2930 do_primitives(scrollbuf, -3);
4692 // Actually use proper ordering (-3 < -2)
4693
1/2
✓ Branch 0 taken 2930 times.
✗ Branch 1 not taken.
5860 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
4694 2930 mapscr* base_scr = screen_handles[0].base_scr;
4695
1/2
✓ Branch 0 taken 2930 times.
✗ Branch 1 not taken.
2930 if (XOR(base_scr->flags7&fLAYER2BG, DMaps[cur_dmap].flags&dmfLAYER2BG))
4696 do_layer(scrollbuf, 0, screen_handles[2], offx, offy);
4697 2930 });
4698
4699 2930 bool l2bg = XOR(origin_scr->flags7&fLAYER2BG, DMaps[cur_dmap].flags&dmfLAYER2BG);
4700
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2930 times.
2930 if (l2bg)
4701 {
4702 do_layer_primitives(scrollbuf, 2);
4703 particles.draw(scrollbuf, true, 2);
4704 }
4705
1/2
✓ Branch 0 taken 2930 times.
✗ Branch 1 not taken.
2930 _do_current_ffc_layer(scrollbuf, -2);
4706
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2930 times.
2930 if (l2bg)
4707 draw_msgstr(2, scrollbuf);
4708
4709
1/2
✓ Branch 0 taken 2930 times.
✗ Branch 1 not taken.
2930 do_primitives(scrollbuf, -2);
4710
4711
1/2
✓ Branch 0 taken 2930 times.
✗ Branch 1 not taken.
2930 _do_current_ffc_layer(scrollbuf, -1);
4712
1/2
✓ Branch 0 taken 2930 times.
✗ Branch 1 not taken.
2930 do_primitives(scrollbuf, -1);
4713 2930 }
4714
4715 // Draw the main combo screens ("layer 0").
4716
1/2
✓ Branch 0 taken 16129780 times.
✗ Branch 1 not taken.
32395878 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
4717 16266098 mapscr* base_scr = screen_handles[0].base_scr;
4718
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16266098 times.
16266098 if (lenscheck(base_scr, 0))
4719 {
4720 16266098 putscr(base_scr, scrollbuf, offx, offy + playing_field_offset);
4721 16266098 }
4722 16266098 });
4723
4724
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16129780 times.
16129780 if (lenscheck(hero_scr, 0))
4725 {
4726
2/2
✓ Branch 0 taken 466049 times.
✓ Branch 1 taken 15663731 times.
16129780 if(!get_qr(qr_PUSHBLOCK_SPRITE_LAYER))
4727
3/4
✓ Branch 0 taken 466049 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4136 times.
✓ Branch 3 taken 461913 times.
470185 if(mblock2.draw(scrollbuf,0))
4728
1/2
✓ Branch 0 taken 4136 times.
✗ Branch 1 not taken.
4136 do_primitives(scrollbuf, SPLAYER_MOVINGBLOCK);
4729 16129780 }
4730
4731 // Lens hints, then primitives, then particles.
4732
6/10
✓ Branch 0 taken 16119751 times.
✓ Branch 1 taken 10029 times.
✓ Branch 2 taken 16119751 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 16119751 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✓ Branch 8 taken 5876 times.
✓ Branch 9 taken 4153 times.
16129780 if((lensclk || (get_debug() && zc_getkey(KEY_L))) && !get_qr(qr_OLDLENSORDER))
4733 {
4734
1/2
✓ Branch 0 taken 5876 times.
✗ Branch 1 not taken.
5876 draw_lens_under(scrollbuf, false);
4735
1/2
✓ Branch 0 taken 5876 times.
✗ Branch 1 not taken.
5876 do_primitives(scrollbuf, SPLAYER_LENS_UNDER_1);
4736 5876 }
4737
4738
2/4
✓ Branch 0 taken 16129780 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 16129780 times.
✗ Branch 3 not taken.
16129780 if(show_layers[0] && lenscheck(hero_scr,0))
4739
1/2
✓ Branch 0 taken 16129780 times.
✗ Branch 1 not taken.
16129780 do_primitives(scrollbuf, 0);
4740
1/2
✓ Branch 0 taken 16129780 times.
✗ Branch 1 not taken.
16129780 particles.draw(scrollbuf, true, 0);
4741
1/2
✓ Branch 0 taken 16129780 times.
✗ Branch 1 not taken.
16129780 _do_current_ffc_layer(scrollbuf, 0);
4742
1/2
✓ Branch 0 taken 16129780 times.
✗ Branch 1 not taken.
16129780 draw_msgstr(0, scrollbuf);
4743
4744
1/2
✓ Branch 0 taken 16129780 times.
✗ Branch 1 not taken.
16129780 set_draw_screen_clip(scrollbuf);
4745
4746 16129780 bool hero_draw_done = false;
4747
4/6
✓ Branch 0 taken 16129780 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 16095028 times.
✓ Branch 3 taken 34752 times.
✓ Branch 4 taken 16095028 times.
✗ Branch 5 not taken.
16129780 bool is_cave_walking = ((Hero.getAction()==climbcovertop)||(Hero.getAction()==climbcoverbottom));
4748
2/2
✓ Branch 0 taken 343259 times.
✓ Branch 1 taken 15786521 times.
16129780 if(!(get_qr(qr_LAYER12UNDERCAVE)))
4749 {
4750
4/4
✓ Branch 0 taken 15784643 times.
✓ Branch 1 taken 1878 times.
✓ Branch 2 taken 88384 times.
✓ Branch 3 taken 15696259 times.
15786521 if(showhero && is_cave_walking)
4751 {
4752 88384 hero_draw_done = true;
4753
3/4
✓ Branch 0 taken 88384 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 53632 times.
✓ Branch 3 taken 34752 times.
88384 if(Hero.getAction()==climbcovertop)
4754 {
4755 34752 cmby2=16;
4756 34752 }
4757
2/4
✓ Branch 0 taken 53632 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 53632 times.
53632 else if(Hero.getAction()==climbcoverbottom)
4758 {
4759 53632 cmby2=-16;
4760 53632 }
4761
4762
1/2
✓ Branch 0 taken 88384 times.
✗ Branch 1 not taken.
88384 decorations.draw2(scrollbuf,true);
4763
1/2
✓ Branch 0 taken 88384 times.
✗ Branch 1 not taken.
88384 Hero.draw(scrollbuf);
4764
1/2
✓ Branch 0 taken 88384 times.
✗ Branch 1 not taken.
88384 decorations.draw(scrollbuf,true);
4765
2/4
✓ Branch 0 taken 88384 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 88384 times.
✗ Branch 3 not taken.
88384 int32_t ccx = (int32_t)Hero.getClimbCoverX();
4766
2/4
✓ Branch 0 taken 88384 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 88384 times.
✗ Branch 3 not taken.
88384 int32_t ccy = (int32_t)Hero.getClimbCoverY();
4767
4768
3/6
✓ Branch 0 taken 88384 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 88384 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 88384 times.
✗ Branch 5 not taken.
88384 overcombo(scrollbuf,ccx-viewport.x,ccy+cmby2+playing_field_offset-viewport.y,MAPCOMBO(ccx,ccy+cmby2),MAPCSET(ccx,ccy+cmby2));
4769
3/6
✓ Branch 0 taken 88384 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 88384 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 88384 times.
✗ Branch 5 not taken.
88384 putcombo(scrollbuf,ccx-viewport.x,ccy+playing_field_offset-viewport.y,MAPCOMBO(ccx,ccy),MAPCSET(ccx,ccy));
4770
4771
4/6
✓ Branch 0 taken 88384 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 88384 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 15232 times.
✓ Branch 5 taken 73152 times.
88384 if(int32_t(Hero.getX())&15)
4772 {
4773
3/6
✓ Branch 0 taken 15232 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 15232 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 15232 times.
✗ Branch 5 not taken.
15232 overcombo(scrollbuf,ccx+16-viewport.x,ccy+cmby2+playing_field_offset-viewport.y,MAPCOMBO(ccx+16,ccy+cmby2),MAPCSET(ccx+16,ccy+cmby2));
4774
3/6
✓ Branch 0 taken 15232 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 15232 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 15232 times.
✗ Branch 5 not taken.
15232 putcombo(scrollbuf,ccx+16-viewport.x,ccy+playing_field_offset-viewport.y,MAPCOMBO(ccx+16,ccy),MAPCSET(ccx+16,ccy));
4775 15232 }
4776 88384 }
4777 15786521 }
4778
4779
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 16129780 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
16129780 if (get_qr(qr_HERO_DIVE_UNDER_LAYER_1) && Hero.isDiving())
4780 {
4781 Hero.draw_under(scrollbuf);
4782 decorations.draw2(scrollbuf,true);
4783 Hero.draw(scrollbuf);
4784 decorations.draw(scrollbuf,true);
4785 hero_draw_done = true;
4786 }
4787
4788
1/2
✓ Branch 0 taken 16129780 times.
✗ Branch 1 not taken.
32395878 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
4789 16266098 do_layer(scrollbuf, 0, screen_handles[1], offx, offy); // LAYER 1
4790 16266098 });
4791
4792
1/2
✓ Branch 0 taken 16129780 times.
✗ Branch 1 not taken.
16129780 do_layer_primitives(scrollbuf, 1);
4793
1/2
✓ Branch 0 taken 16129780 times.
✗ Branch 1 not taken.
16129780 particles.draw(scrollbuf, true, 1);
4794
1/2
✓ Branch 0 taken 16129780 times.
✗ Branch 1 not taken.
16129780 _do_current_ffc_layer(scrollbuf, 1);
4795
1/2
✓ Branch 0 taken 16129780 times.
✗ Branch 1 not taken.
16129780 draw_msgstr(1, scrollbuf);
4796
4797 // Handle layer 2 NOT being used as background layers.
4798
1/2
✓ Branch 0 taken 16129780 times.
✗ Branch 1 not taken.
32395878 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
4799 16266098 mapscr* base_scr = screen_handles[0].base_scr;
4800
2/2
✓ Branch 0 taken 142121 times.
✓ Branch 1 taken 16123977 times.
16266098 if (!XOR(base_scr->flags7&fLAYER2BG, DMaps[cur_dmap].flags&dmfLAYER2BG))
4801 16123977 do_layer(scrollbuf, 0, screen_handles[2], offx, offy);
4802 16266098 });
4803
4804
2/2
✓ Branch 0 taken 15987659 times.
✓ Branch 1 taken 142121 times.
16129780 if(!XOR(origin_scr->flags7&fLAYER2BG, DMaps[cur_dmap].flags&dmfLAYER2BG))
4805 {
4806
1/2
✓ Branch 0 taken 15987659 times.
✗ Branch 1 not taken.
15987659 do_layer_primitives(scrollbuf, 2);
4807
1/2
✓ Branch 0 taken 15987659 times.
✗ Branch 1 not taken.
15987659 particles.draw(scrollbuf, true, 2);
4808 15987659 }
4809
1/2
✓ Branch 0 taken 16129780 times.
✗ Branch 1 not taken.
16129780 _do_current_ffc_layer(scrollbuf, 2);
4810
2/2
✓ Branch 0 taken 15987659 times.
✓ Branch 1 taken 142121 times.
16129780 if(!XOR(origin_scr->flags7&fLAYER2BG, DMaps[cur_dmap].flags&dmfLAYER2BG))
4811
1/2
✓ Branch 0 taken 15987659 times.
✗ Branch 1 not taken.
15987659 draw_msgstr(2, scrollbuf);
4812
4813
1/2
✓ Branch 0 taken 16129780 times.
✗ Branch 1 not taken.
16129780 do_primitives(scrollbuf, SPLAYER_FFC_DRAW);
4814
4815
2/2
✓ Branch 0 taken 15786521 times.
✓ Branch 1 taken 343259 times.
16129780 if(get_qr(qr_LAYER12UNDERCAVE))
4816 {
4817
2/4
✓ Branch 0 taken 343259 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 343259 times.
343259 if(showhero && is_cave_walking)
4818 {
4819 hero_draw_done = true;
4820 if(Hero.getAction()==climbcovertop)
4821 {
4822 cmby2=16;
4823 }
4824 else if(Hero.getAction()==climbcoverbottom)
4825 {
4826 cmby2=-16;
4827 }
4828
4829 decorations.draw2(scrollbuf,true);
4830 Hero.draw(scrollbuf);
4831 decorations.draw(scrollbuf,true);
4832 int32_t ccx = (int32_t)(Hero.getClimbCoverX());
4833 int32_t ccy = (int32_t)(Hero.getClimbCoverY());
4834
4835 overcombo(scrollbuf,ccx-viewport.x,ccy+cmby2+playing_field_offset-viewport.y,MAPCOMBO(ccx,ccy+cmby2),MAPCSET(ccx,ccy+cmby2));
4836 putcombo(scrollbuf,ccx-viewport.x,ccy+playing_field_offset-viewport.y,MAPCOMBO(ccx,ccy),MAPCSET(ccx,ccy));
4837
4838 if(int32_t(Hero.getX())&15)
4839 {
4840 overcombo(scrollbuf,ccx+16-viewport.x,ccy+cmby2+playing_field_offset-viewport.y,MAPCOMBO(ccx+16,ccy+cmby2),MAPCSET(ccx+16,ccy+cmby2));
4841 putcombo(scrollbuf,ccx+16-viewport.x,ccy+playing_field_offset-viewport.y,MAPCOMBO(ccx+16,ccy),MAPCSET(ccx+16,ccy));
4842 }
4843 }
4844 343259 }
4845
4846
2/2
✓ Branch 0 taken 466049 times.
✓ Branch 1 taken 15663731 times.
16129780 if (get_qr(qr_PUSHBLOCK_SPRITE_LAYER))
4847 {
4848
1/2
✓ Branch 0 taken 15663731 times.
✗ Branch 1 not taken.
31463780 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
4849 15800049 do_layer(scrollbuf, -2, screen_handles[0], offx, offy); // push blocks!
4850
2/2
✓ Branch 0 taken 14478915 times.
✓ Branch 1 taken 1321134 times.
15800049 if(get_qr(qr_PUSHBLOCK_LAYER_1_2))
4851 {
4852 1321134 do_layer(scrollbuf, -2, screen_handles[1], offx, offy); // push blocks!
4853 1321134 do_layer(scrollbuf, -2, screen_handles[2], offx, offy); // push blocks!
4854 1321134 }
4855 15800049 });
4856
4857
1/2
✓ Branch 0 taken 15663731 times.
✗ Branch 1 not taken.
15663731 do_primitives(scrollbuf, SPLAYER_PUSHBLOCK);
4858 15663731 }
4859
4860 // Show walkflags cheat
4861
2/4
✓ Branch 0 taken 16129780 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 16129780 times.
16129780 if (show_walkflags || show_effectflags)
4862 {
4863 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
4864 do_walkflags(screen_handles, offx, offy);
4865 do_effectflags(screen_handles[0].base_scr, offx, offy);
4866 });
4867
4868 do_walkflags(0, 0);
4869 }
4870
4871
1/2
✓ Branch 0 taken 16129780 times.
✗ Branch 1 not taken.
16129780 putscrdoors(nearby_screens, scrollbuf, 0, playing_field_offset);
4872
4873 // Lens hints, doors etc.
4874
4/8
✓ Branch 0 taken 16119751 times.
✓ Branch 1 taken 10029 times.
✓ Branch 2 taken 16119751 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 16119751 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
16129780 if(lensclk || (get_debug() && zc_getkey(KEY_L)))
4875 {
4876
2/2
✓ Branch 0 taken 4153 times.
✓ Branch 1 taken 5876 times.
10029 if(get_qr(qr_OLDLENSORDER))
4877 {
4878
1/2
✓ Branch 0 taken 4153 times.
✗ Branch 1 not taken.
4153 draw_lens_under(scrollbuf, false);
4879
1/2
✓ Branch 0 taken 4153 times.
✗ Branch 1 not taken.
4153 do_primitives(scrollbuf, SPLAYER_LENS_UNDER_1);
4880 4153 }
4881
4882
1/2
✓ Branch 0 taken 10029 times.
✗ Branch 1 not taken.
10029 draw_lens_under(scrollbuf, true);
4883
1/2
✓ Branch 0 taken 10029 times.
✗ Branch 1 not taken.
10029 do_primitives(scrollbuf, SPLAYER_LENS_UNDER_2);
4884 10029 }
4885
4886 // Blit those layers onto dest (framebuf)
4887
4888
1/2
✓ Branch 0 taken 16129780 times.
✗ Branch 1 not taken.
16129780 set_draw_screen_clip(dest);
4889
4890
1/2
✓ Branch 0 taken 16129780 times.
✗ Branch 1 not taken.
16129780 blit(scrollbuf, dest, 0, 0, 0, 0, 256, 232);
4891
4892 // After this point, scrollbuf is no longer drawn to - so things like dosubscr have access to a "partially rendered" frame.
4893 // I think only used for COOLSCROLL==0? Seems like a silly feature...
4894
4895 // Draw the subscreen, without clipping
4896
2/2
✓ Branch 0 taken 9251384 times.
✓ Branch 1 taken 6878396 times.
16129780 if(!get_qr(qr_SUBSCREENOVERSPRITES))
4897 {
4898 9251384 bool dotime = false;
4899
4/6
✓ Branch 0 taken 9251384 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3412853 times.
✓ Branch 3 taken 5838531 times.
✓ Branch 4 taken 3412853 times.
✗ Branch 5 not taken.
9251384 if (replay_version_check(22)) dotime = game->should_show_time();
4900
1/2
✓ Branch 0 taken 9251384 times.
✗ Branch 1 not taken.
9251384 put_passive_subscr(dest, 0, 0, dotime, sspUP);
4901 9251384 }
4902
4903 // Draw some sprites onto dest
4904
1/2
✓ Branch 0 taken 16129780 times.
✗ Branch 1 not taken.
16129780 set_clip_rect(dest,0,0,256,232);
4905
4906
2/2
✓ Branch 0 taken 99496 times.
✓ Branch 1 taken 16030284 times.
16129780 if(!(pricesdisplaybuf->clip))
4907 {
4908
1/2
✓ Branch 0 taken 99496 times.
✗ Branch 1 not taken.
99496 masked_blit(pricesdisplaybuf,dest,0,0,0,playing_field_offset,256,176);
4909 99496 }
4910
4911
5/6
✓ Branch 0 taken 16084154 times.
✓ Branch 1 taken 45626 times.
✓ Branch 2 taken 6328 times.
✓ Branch 3 taken 16077826 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 6328 times.
16129780 if (!is_extended_height_mode() && is_in_scrolling_region() && !get_qr(qr_SUBSCREENOVERSPRITES))
4912 add_clip_rect(dest, 0, playing_field_offset, dest->w, dest->h);
4913
4914
4/4
✓ Branch 0 taken 16127902 times.
✓ Branch 1 taken 1878 times.
✓ Branch 2 taken 16039518 times.
✓ Branch 3 taken 88384 times.
16129780 if(showhero && !hero_draw_done)
4915 {
4916
1/2
✓ Branch 0 taken 16039518 times.
✗ Branch 1 not taken.
16039518 Hero.draw_under(dest);
4917
4918
3/4
✓ Branch 0 taken 16039518 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 141385 times.
✓ Branch 3 taken 15898133 times.
16039518 if(Hero.isSwimming())
4919 {
4920
1/2
✓ Branch 0 taken 141385 times.
✗ Branch 1 not taken.
141385 decorations.draw2(dest,true);
4921
1/2
✓ Branch 0 taken 141385 times.
✗ Branch 1 not taken.
141385 Hero.draw(dest);
4922
1/2
✓ Branch 0 taken 141385 times.
✗ Branch 1 not taken.
141385 decorations.draw(dest,true);
4923 141385 hero_draw_done = true;
4924 141385 }
4925 16039518 }
4926
4927 16129780 set<sprite*, SpriteSorter> sorted_sprites;
4928 16129780 vector<sprite*> temp_sprites;
4929 16129780 std::function<bool(sprite&)> add_sprite = [&](sprite& spr)
4930 {
4931 sorted_sprites.insert(&spr);
4932 return false;
4933 };
4934
4935
2/2
✓ Branch 0 taken 16126850 times.
✓ Branch 1 taken 2930 times.
16129780 if (classic_draw)
4936 {
4937
2/2
✓ Branch 0 taken 26095 times.
✓ Branch 1 taken 16100755 times.
16126850 if(drawguys)
4938 {
4939
4/4
✓ Branch 0 taken 1982674 times.
✓ Branch 1 taken 14118081 times.
✓ Branch 2 taken 991089 times.
✓ Branch 3 taken 991585 times.
16100755 if(get_qr(qr_NOFLICKER) || (frame&1))
4940 {
4941 // Just clips sprites if in a repeating, smooth maze.
4942
2/2
✓ Branch 0 taken 15099956 times.
✓ Branch 1 taken 9214 times.
15109170 bool do_clip = maze_state.active && maze_state.loopy;
4943
4944
1/2
✓ Branch 0 taken 15109170 times.
✗ Branch 1 not taken.
15109170 if(!get_qr(qr_OLD_WEAPON_DRAW_ANIMATE_TIMING))
4945 {
4946 if (do_clip)
4947 {
4948 Ewpns.drawshadow_smooth_maze(dest,get_qr(qr_TRANSSHADOWS));
4949 Lwpns.drawshadow_smooth_maze(dest,get_qr(qr_TRANSSHADOWS));
4950 }
4951 else
4952 {
4953 Ewpns.drawshadow(dest,get_qr(qr_TRANSSHADOWS),true);
4954 Lwpns.drawshadow(dest,get_qr(qr_TRANSSHADOWS),true);
4955 }
4956 }
4957
3/4
✓ Branch 0 taken 24914244 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 9805074 times.
✓ Branch 3 taken 15109170 times.
24914244 for(int32_t i=0; i<Ewpns.Count(); i++)
4958 {
4959
3/4
✓ Branch 0 taken 9805074 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 250942 times.
✓ Branch 3 taken 9554132 times.
9805074 if(((weapon *)Ewpns.spr(i))->behind)
4960
2/4
✓ Branch 0 taken 250942 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 250942 times.
✗ Branch 3 not taken.
250942 Ewpns.spr(i)->draw(dest);
4961 9805074 }
4962
1/2
✓ Branch 0 taken 15109170 times.
✗ Branch 1 not taken.
15109170 do_primitives(dest, SPLAYER_EWEAP_BEHIND_DRAW);
4963
4964
3/4
✓ Branch 0 taken 21293161 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 6183991 times.
✓ Branch 3 taken 15109170 times.
21293161 for(int32_t i=0; i<Lwpns.Count(); i++)
4965 {
4966
3/4
✓ Branch 0 taken 6183991 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1206996 times.
✓ Branch 3 taken 4976995 times.
6183991 if(((weapon *)Lwpns.spr(i))->behind)
4967
2/4
✓ Branch 0 taken 1206996 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1206996 times.
✗ Branch 3 not taken.
1206996 Lwpns.spr(i)->draw(dest);
4968 6183991 }
4969
1/2
✓ Branch 0 taken 15109170 times.
✗ Branch 1 not taken.
15109170 do_primitives(dest, SPLAYER_LWEAP_BEHIND_DRAW);
4970
4971
6/6
✓ Branch 0 taken 10372306 times.
✓ Branch 1 taken 4736864 times.
✓ Branch 2 taken 1348300 times.
✓ Branch 3 taken 9024006 times.
✓ Branch 4 taken 674011 times.
✓ Branch 5 taken 674289 times.
15109170 if(get_qr(qr_SHADOWS)&&(!get_qr(qr_SHADOWSFLICKER)||frame&1))
4972 {
4973
2/2
✓ Branch 0 taken 3658 times.
✓ Branch 1 taken 9694359 times.
9698017 if (do_clip)
4974
1/2
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
3658 guys.drawshadow_smooth_maze(dest,get_qr(qr_TRANSSHADOWS)!=0);
4975 else
4976
1/2
✓ Branch 0 taken 9694359 times.
✗ Branch 1 not taken.
9694359 guys.drawshadow(dest,get_qr(qr_TRANSSHADOWS)!=0,true);
4977 9698017 }
4978
2/2
✓ Branch 0 taken 3658 times.
✓ Branch 1 taken 15105512 times.
15109170 if (do_clip)
4979
1/2
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
3658 guys.draw_smooth_maze(dest);
4980 else
4981
1/2
✓ Branch 0 taken 15105512 times.
✗ Branch 1 not taken.
15105512 guys.draw(dest,true);
4982
2/2
✓ Branch 0 taken 3658 times.
✓ Branch 1 taken 15105512 times.
15109170 if (do_clip)
4983 {
4984 3658 int maze_screen = maze_state.scr->screen;
4985
1/2
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
3658 auto [sx, sy] = translate_screen_coordinates_to_world(maze_screen);
4986
5/10
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3658 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 3658 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 3658 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 3658 times.
✗ Branch 9 not taken.
18290 set_clip_rect(dest, sx - viewport.x, sy - viewport.y, sx + 256 - viewport.x, sy + 176 - viewport.y);
4987 3658 }
4988
1/2
✓ Branch 0 taken 15109170 times.
✗ Branch 1 not taken.
15109170 do_primitives(dest, SPLAYER_NPC_DRAW);
4989
2/2
✓ Branch 0 taken 3658 times.
✓ Branch 1 taken 15105512 times.
15109170 if (do_clip)
4990
1/2
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
3658 clear_clip_rect(dest);
4991
4992
1/2
✓ Branch 0 taken 15109170 times.
✗ Branch 1 not taken.
15109170 chainlinks.draw(dest,true);
4993
1/2
✓ Branch 0 taken 15109170 times.
✗ Branch 1 not taken.
15109170 do_primitives(dest, SPLAYER_CHAINLINK_DRAW);
4994 //Lwpns.draw(dest,true);
4995
4996
3/4
✓ Branch 0 taken 24914244 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 9805074 times.
✓ Branch 3 taken 15109170 times.
24914244 for(int32_t i=0; i<Ewpns.Count(); i++)
4997 {
4998
3/4
✓ Branch 0 taken 9805074 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 9554132 times.
✓ Branch 3 taken 250942 times.
9805074 if(!((weapon *)Ewpns.spr(i))->behind)
4999
2/4
✓ Branch 0 taken 9554132 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 9554132 times.
✗ Branch 3 not taken.
9554132 Ewpns.spr(i)->draw(dest);
5000 9805074 }
5001
1/2
✓ Branch 0 taken 15109170 times.
✗ Branch 1 not taken.
15109170 do_primitives(dest, SPLAYER_EWEAP_FRONT_DRAW);
5002
5003
3/4
✓ Branch 0 taken 21293161 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 6183991 times.
✓ Branch 3 taken 15109170 times.
21293161 for(int32_t i=0; i<Lwpns.Count(); i++)
5004 {
5005
3/4
✓ Branch 0 taken 6183991 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4976995 times.
✓ Branch 3 taken 1206996 times.
6183991 if(!((weapon *)Lwpns.spr(i))->behind)
5006
2/4
✓ Branch 0 taken 4976995 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4976995 times.
✗ Branch 3 not taken.
4976995 Lwpns.spr(i)->draw(dest);
5007 6183991 }
5008
1/2
✓ Branch 0 taken 15109170 times.
✗ Branch 1 not taken.
15109170 do_primitives(dest, SPLAYER_LWEAP_FRONT_DRAW);
5009
5010
2/2
✓ Branch 0 taken 3658 times.
✓ Branch 1 taken 15105512 times.
15109170 if (do_clip)
5011
1/2
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
3658 items.draw_smooth_maze(dest);
5012 else
5013
1/2
✓ Branch 0 taken 15105512 times.
✗ Branch 1 not taken.
15105512 items.draw(dest,true);
5014
2/2
✓ Branch 0 taken 3658 times.
✓ Branch 1 taken 15105512 times.
15109170 if (do_clip)
5015 {
5016 3658 int maze_screen = maze_state.scr->screen;
5017
1/2
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
3658 auto [sx, sy] = translate_screen_coordinates_to_world(maze_screen);
5018
5/10
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3658 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 3658 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 3658 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 3658 times.
✗ Branch 9 not taken.
18290 set_clip_rect(dest, sx - viewport.x, sy - viewport.y, sx + 256 - viewport.x, sy + 176 - viewport.y);
5019 3658 }
5020
1/2
✓ Branch 0 taken 15109170 times.
✗ Branch 1 not taken.
15109170 do_primitives(dest, SPLAYER_ITEMSPRITE_DRAW);
5021
2/2
✓ Branch 0 taken 3658 times.
✓ Branch 1 taken 15105512 times.
15109170 if (do_clip)
5022
1/2
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
3658 clear_clip_rect(dest);
5023 15109170 }
5024 else
5025 {
5026
3/4
✓ Branch 0 taken 1496957 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 505372 times.
✓ Branch 3 taken 991585 times.
1496957 for(int32_t i=0; i<Ewpns.Count(); i++)
5027 {
5028
3/4
✓ Branch 0 taken 505372 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 8645 times.
✓ Branch 3 taken 496727 times.
505372 if(((weapon *)Ewpns.spr(i))->behind)
5029
2/4
✓ Branch 0 taken 8645 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 8645 times.
✗ Branch 3 not taken.
8645 Ewpns.spr(i)->draw(dest);
5030 505372 }
5031
1/2
✓ Branch 0 taken 991585 times.
✗ Branch 1 not taken.
991585 do_primitives(dest, SPLAYER_EWEAP_BEHIND_DRAW);
5032
5033
3/4
✓ Branch 0 taken 1222731 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 231146 times.
✓ Branch 3 taken 991585 times.
1222731 for(int32_t i=0; i<Lwpns.Count(); i++)
5034 {
5035
2/4
✓ Branch 0 taken 231146 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 231146 times.
231146 if(((weapon *)Lwpns.spr(i))->behind)
5036 Lwpns.spr(i)->draw(dest);
5037 231146 }
5038
1/2
✓ Branch 0 taken 991585 times.
✗ Branch 1 not taken.
991585 do_primitives(dest, SPLAYER_LWEAP_BEHIND_DRAW);
5039
5040
3/4
✓ Branch 0 taken 228620 times.
✓ Branch 1 taken 762965 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 228620 times.
991585 if(get_qr(qr_SHADOWS)&&(!get_qr(qr_SHADOWSFLICKER)||frame&1))
5041 {
5042
1/2
✓ Branch 0 taken 228620 times.
✗ Branch 1 not taken.
228620 guys.drawshadow(dest,get_qr(qr_TRANSSHADOWS)!=0,true);
5043 228620 }
5044
5045
1/2
✓ Branch 0 taken 991585 times.
✗ Branch 1 not taken.
991585 items.draw(dest,false);
5046
1/2
✓ Branch 0 taken 991585 times.
✗ Branch 1 not taken.
991585 do_primitives(dest, SPLAYER_ITEMSPRITE_DRAW);
5047
1/2
✓ Branch 0 taken 991585 times.
✗ Branch 1 not taken.
991585 chainlinks.draw(dest,false);
5048
1/2
✓ Branch 0 taken 991585 times.
✗ Branch 1 not taken.
991585 do_primitives(dest, SPLAYER_CHAINLINK_DRAW);
5049 //Lwpns.draw(dest,false);
5050
1/2
✓ Branch 0 taken 991585 times.
✗ Branch 1 not taken.
991585 guys.draw(dest,false);
5051
1/2
✓ Branch 0 taken 991585 times.
✗ Branch 1 not taken.
991585 do_primitives(dest, SPLAYER_NPC_DRAW);
5052
5053
3/4
✓ Branch 0 taken 1496957 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 505372 times.
✓ Branch 3 taken 991585 times.
1496957 for(int32_t i=0; i<Ewpns.Count(); i++)
5054 {
5055
3/4
✓ Branch 0 taken 505372 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 496727 times.
✓ Branch 3 taken 8645 times.
505372 if(!((weapon *)Ewpns.spr(i))->behind)
5056 {
5057
2/4
✓ Branch 0 taken 496727 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 496727 times.
✗ Branch 3 not taken.
496727 Ewpns.spr(i)->draw(dest);
5058 496727 }
5059 505372 }
5060
1/2
✓ Branch 0 taken 991585 times.
✗ Branch 1 not taken.
991585 do_primitives(dest, SPLAYER_EWEAP_FRONT_DRAW);
5061
5062
3/4
✓ Branch 0 taken 1222731 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 231146 times.
✓ Branch 3 taken 991585 times.
1222731 for(int32_t i=0; i<Lwpns.Count(); i++)
5063 {
5064
2/4
✓ Branch 0 taken 231146 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 231146 times.
✗ Branch 3 not taken.
231146 if(!((weapon *)Lwpns.spr(i))->behind)
5065 {
5066
2/4
✓ Branch 0 taken 231146 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 231146 times.
✗ Branch 3 not taken.
231146 Lwpns.spr(i)->draw(dest);
5067 231146 }
5068 231146 }
5069
1/2
✓ Branch 0 taken 991585 times.
✗ Branch 1 not taken.
991585 do_primitives(dest, SPLAYER_LWEAP_FRONT_DRAW);
5070 }
5071
5072
1/2
✓ Branch 0 taken 16100755 times.
✗ Branch 1 not taken.
16100755 guys.draw2(dest,true);
5073 16100755 }
5074
5075
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16126850 times.
16126850 if(mirror_portal.destdmap > -1)
5076 mirror_portal.draw(dest);
5077
1/2
✓ Branch 0 taken 16126850 times.
✗ Branch 1 not taken.
16126850 portals.draw(dest,true);
5078
5079
4/4
✓ Branch 0 taken 16124972 times.
✓ Branch 1 taken 1878 times.
✓ Branch 2 taken 88384 times.
✓ Branch 3 taken 16036588 times.
16126850 if(showhero && !is_cave_walking)
5080 {
5081
2/2
✓ Branch 0 taken 15576955 times.
✓ Branch 1 taken 459633 times.
16036588 if(get_qr(qr_PUSHBLOCK_SPRITE_LAYER))
5082 {
5083
1/2
✓ Branch 0 taken 15576955 times.
✗ Branch 1 not taken.
15576955 mblock2.draw(dest,-1);
5084
1/2
✓ Branch 0 taken 15576955 times.
✗ Branch 1 not taken.
15576955 do_primitives(dest, SPLAYER_MOVINGBLOCK);
5085 15576955 }
5086
2/2
✓ Branch 0 taken 15895203 times.
✓ Branch 1 taken 141385 times.
16036588 if(!hero_draw_done)
5087 {
5088
8/12
✓ Branch 0 taken 15895203 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 15895203 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 15876033 times.
✓ Branch 5 taken 19170 times.
✓ Branch 6 taken 15876033 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 15876033 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 1370 times.
✓ Branch 11 taken 15893833 times.
15895203 if((Hero.getZ()>0 || Hero.getFakeZ()>0) &&(!get_qr(qr_SHADOWSFLICKER)||frame&1))
5089 {
5090
2/2
✓ Branch 0 taken 18485 times.
✓ Branch 1 taken 15876718 times.
15895203 Hero.drawshadow(dest,get_qr(qr_TRANSSHADOWS)!=0);
5091 18485 }
5092
5093
6/8
✓ Branch 0 taken 15895203 times.
✓ Branch 1 taken 15876718 times.
✓ Branch 2 taken 15895203 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 15895203 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 15881139 times.
✓ Branch 7 taken 14064 times.
18485 if(Hero.getZ() <= (zfix)zinit.jump_hero_layer_threshold)
5094 {
5095
1/2
✓ Branch 0 taken 15881139 times.
✗ Branch 1 not taken.
15881139 decorations.draw2(dest,true);
5096
1/2
✓ Branch 0 taken 15881139 times.
✗ Branch 1 not taken.
15881139 Hero.draw(dest);
5097
1/2
✓ Branch 0 taken 15881139 times.
✗ Branch 1 not taken.
15881139 decorations.draw(dest,true);
5098 15881139 hero_draw_done = true;
5099 15881139 }
5100 15895203 }
5101 16036588 }
5102
5103
3/4
✓ Branch 0 taken 56544418 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 40417568 times.
✓ Branch 3 taken 16126850 times.
56544418 for(int32_t i=0; i<guys.Count(); i++)
5104 {
5105
3/4
✓ Branch 0 taken 40417568 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 16520322 times.
✓ Branch 3 taken 23897246 times.
40417568 if(((enemy*)guys.spr(i))->type == eeWALK)
5106 {
5107
3/4
✓ Branch 0 taken 16520322 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 7965 times.
✓ Branch 3 taken 16512357 times.
16520322 if(((eStalfos*)guys.spr(i))->hashero)
5108 {
5109
2/4
✓ Branch 0 taken 7965 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 7965 times.
✗ Branch 3 not taken.
7965 guys.spr(i)->draw(dest);
5110 7965 }
5111 16520322 }
5112
5113
3/4
✓ Branch 0 taken 40417568 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 507162 times.
✓ Branch 3 taken 39910406 times.
40417568 if(((enemy*)guys.spr(i))->type == eeWALLM)
5114 {
5115
3/4
✓ Branch 0 taken 507162 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1329 times.
✓ Branch 3 taken 505833 times.
507162 if(((eWallM*)guys.spr(i))->hashero)
5116 {
5117
2/4
✓ Branch 0 taken 1329 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1329 times.
✗ Branch 3 not taken.
1329 guys.spr(i)->draw(dest);
5118 1329 }
5119 507162 }
5120
5121
11/20
✓ Branch 0 taken 40417568 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 40417568 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 40417568 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 40417568 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 40417568 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 40417568 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 40417568 times.
✗ Branch 13 not taken.
✓ Branch 14 taken 40417568 times.
✗ Branch 15 not taken.
✓ Branch 16 taken 40417568 times.
✗ Branch 17 not taken.
✓ Branch 18 taken 1523506 times.
✓ Branch 19 taken 38894062 times.
40417568 if(guys.spr(i)->z+guys.spr(i)->fakez > Hero.getZ()+Hero.getFakeZ())
5122 {
5123 //Jumping enemies in front of Hero.
5124
2/4
✓ Branch 0 taken 1523506 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1523506 times.
✗ Branch 3 not taken.
1523506 guys.spr(i)->draw(dest);
5125 1523506 }
5126
1/2
✓ Branch 0 taken 40417568 times.
✗ Branch 1 not taken.
40417568 do_primitives(dest, SPLAYER_NPC_ABOVEPLAYER_DRAW);
5127 40417568 }
5128 16126850 }
5129 else
5130 {
5131
1/2
✓ Branch 0 taken 2930 times.
✗ Branch 1 not taken.
2930 if(drawguys)
5132 {
5133
2/4
✓ Branch 0 taken 2930 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2930 times.
✗ Branch 3 not taken.
2930 chainlinks.forEach(add_sprite);
5134
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 2930 times.
✓ Branch 2 taken 2930 times.
✗ Branch 3 not taken.
5860 bool show_enemy_shadows = (get_qr(qr_SHADOWS)&&(!get_qr(qr_SHADOWSFLICKER)||frame&1));
5135 25837 auto add_spr_shadow = [&](sprite& spr)
5136 {
5137 22907 sorted_sprites.insert(&spr);
5138
3/4
✓ Branch 0 taken 1291 times.
✓ Branch 1 taken 21616 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1291 times.
22907 if(spr.total_z() > 0 && spr.can_drawshadow())
5139 {
5140
1/2
✓ Branch 0 taken 1291 times.
✗ Branch 1 not taken.
1291 tempsprite_shadow* shadow = new tempsprite_shadow(&spr);
5141 1291 sorted_sprites.insert(shadow);
5142 1291 temp_sprites.push_back(shadow);
5143 1291 }
5144 22907 return false;
5145 };
5146
1/2
✓ Branch 0 taken 2930 times.
✗ Branch 1 not taken.
2930 Lwpns.forEach(add_spr_shadow);
5147
1/2
✓ Branch 0 taken 2930 times.
✗ Branch 1 not taken.
2930 Ewpns.forEach(add_spr_shadow);
5148
1/2
✓ Branch 0 taken 2930 times.
✗ Branch 1 not taken.
2930 items.forEach(add_spr_shadow);
5149
4/14
✓ Branch 0 taken 2930 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 2930 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 2930 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✓ Branch 9 taken 2930 times.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
2930 guys.forEach(show_enemy_shadows ? add_spr_shadow : add_sprite);
5150 2930 }
5151
2/4
✓ Branch 0 taken 2930 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2930 times.
✗ Branch 3 not taken.
2930 if(showhero && !hero_draw_done)
5152 {
5153
1/2
✓ Branch 0 taken 2930 times.
✗ Branch 1 not taken.
2930 sorted_sprites.insert(&Hero);
5154
9/14
✓ Branch 0 taken 2930 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2930 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2290 times.
✓ Branch 5 taken 640 times.
✓ Branch 6 taken 2290 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 2290 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✓ Branch 11 taken 2930 times.
✓ Branch 12 taken 2290 times.
✓ Branch 13 taken 2290 times.
2930 if((Hero.getZ()>0 || Hero.getFakeZ()>0) &&(!get_qr(qr_SHADOWSFLICKER)||frame&1))
5155 {
5156
3/4
✓ Branch 0 taken 640 times.
✓ Branch 1 taken 4580 times.
✓ Branch 2 taken 640 times.
✗ Branch 3 not taken.
5220 tempsprite_shadow* shadow = new tempsprite_shadow(&Hero);
5157
1/2
✓ Branch 0 taken 640 times.
✗ Branch 1 not taken.
640 sorted_sprites.insert(shadow);
5158
1/2
✓ Branch 0 taken 640 times.
✗ Branch 1 not taken.
640 temp_sprites.push_back(shadow);
5159 640 }
5160 2930 }
5161
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2930 times.
2930 if(mirror_portal.destdmap > -1)
5162 sorted_sprites.insert(&mirror_portal);
5163
2/4
✓ Branch 0 taken 2930 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2930 times.
✗ Branch 3 not taken.
2930 portals.forEach(add_sprite);
5164
1/2
✓ Branch 0 taken 2930 times.
✗ Branch 1 not taken.
2930 if(get_qr(qr_PUSHBLOCK_SPRITE_LAYER))
5165
1/2
✓ Branch 0 taken 2930 times.
✗ Branch 1 not taken.
2930 sorted_sprites.insert(&mblock2);
5166 }
5167 16129780 auto sprite_it = sorted_sprites.begin();
5168
2/2
✓ Branch 0 taken 2930 times.
✓ Branch 1 taken 16126850 times.
16129780 if (!classic_draw)
5169
1/2
✓ Branch 0 taken 2930 times.
✗ Branch 1 not taken.
2930 draw_sprites(dest, sorted_sprites, sprite_it, zinit.sprite_z_thresholds[SPRITE_THRESHOLD_GROUND]);
5170
5171 // Draw some layers onto dest
5172
1/2
✓ Branch 0 taken 16129780 times.
✗ Branch 1 not taken.
16129780 set_draw_screen_clip(dest);
5173
5/6
✓ Branch 0 taken 16084154 times.
✓ Branch 1 taken 45626 times.
✓ Branch 2 taken 6328 times.
✓ Branch 3 taken 16077826 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 6328 times.
16129780 if (!is_extended_height_mode() && is_in_scrolling_region() && !get_qr(qr_SUBSCREENOVERSPRITES))
5174 add_clip_rect(dest, 0, playing_field_offset, dest->w, dest->h);
5175
5176 // Handle layer 3 NOT being used as background layers.
5177
1/2
✓ Branch 0 taken 16129780 times.
✗ Branch 1 not taken.
32395878 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
5178 16266098 mapscr* base_scr = screen_handles[0].base_scr;
5179
2/2
✓ Branch 0 taken 234564 times.
✓ Branch 1 taken 16031534 times.
16266098 if (!XOR(base_scr->flags7&fLAYER3BG, DMaps[cur_dmap].flags&dmfLAYER3BG))
5180 16031534 do_layer(dest, 0, screen_handles[3], offx, offy);
5181 16266098 });
5182
5183
2/2
✓ Branch 0 taken 2930 times.
✓ Branch 1 taken 16126850 times.
16129780 if (!classic_draw)
5184
1/2
✓ Branch 0 taken 2930 times.
✗ Branch 1 not taken.
2930 draw_sprites(dest, sorted_sprites, sprite_it, zinit.sprite_z_thresholds[SPRITE_THRESHOLD_3]);
5185
5186
2/2
✓ Branch 0 taken 15895216 times.
✓ Branch 1 taken 234564 times.
16129780 if(!XOR(origin_scr->flags7&fLAYER3BG, DMaps[cur_dmap].flags&dmfLAYER3BG))
5187 {
5188
1/2
✓ Branch 0 taken 15895216 times.
✗ Branch 1 not taken.
15895216 do_layer_primitives(dest, 3);
5189
1/2
✓ Branch 0 taken 15895216 times.
✗ Branch 1 not taken.
15895216 particles.draw(dest, true, 3);
5190 15895216 }
5191
1/2
✓ Branch 0 taken 16129780 times.
✗ Branch 1 not taken.
16129780 _do_current_ffc_layer(dest, 3);
5192
2/2
✓ Branch 0 taken 15895216 times.
✓ Branch 1 taken 234564 times.
16129780 if(!XOR(origin_scr->flags7&fLAYER3BG, DMaps[cur_dmap].flags&dmfLAYER3BG))
5193
1/2
✓ Branch 0 taken 15895216 times.
✗ Branch 1 not taken.
15895216 draw_msgstr(3);
5194
5195
5196
1/2
✓ Branch 0 taken 16129780 times.
✗ Branch 1 not taken.
32395878 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
5197 16266098 do_layer(dest, 0, screen_handles[4], offx, offy);
5198 16266098 });
5199
5200
2/2
✓ Branch 0 taken 2930 times.
✓ Branch 1 taken 16126850 times.
16129780 if (!classic_draw)
5201
1/2
✓ Branch 0 taken 2930 times.
✗ Branch 1 not taken.
2930 draw_sprites(dest, sorted_sprites, sprite_it, zinit.sprite_z_thresholds[SPRITE_THRESHOLD_4]);
5202
5203
1/2
✓ Branch 0 taken 16129780 times.
✗ Branch 1 not taken.
16129780 do_layer_primitives(dest, 4);
5204
1/2
✓ Branch 0 taken 16129780 times.
✗ Branch 1 not taken.
16129780 particles.draw(dest, true, 4);
5205
1/2
✓ Branch 0 taken 16129780 times.
✗ Branch 1 not taken.
16129780 _do_current_ffc_layer(dest, 4);
5206
1/2
✓ Branch 0 taken 16129780 times.
✗ Branch 1 not taken.
16129780 draw_msgstr(4);
5207
5208
1/2
✓ Branch 0 taken 16129780 times.
✗ Branch 1 not taken.
32395878 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
5209 16266098 do_layer(dest, -1, screen_handles[0], offx, offy);
5210
2/2
✓ Branch 0 taken 14402748 times.
✓ Branch 1 taken 1863350 times.
16266098 if (get_qr(qr_OVERHEAD_COMBOS_L1_L2))
5211 {
5212 1863350 do_layer(dest, -1, screen_handles[1], offx, offy);
5213 1863350 do_layer(dest, -1, screen_handles[2], offx, offy);
5214 1863350 }
5215 16266098 });
5216
5217
1/2
✓ Branch 0 taken 16129780 times.
✗ Branch 1 not taken.
16129780 do_primitives(dest, SPLAYER_OVERHEAD_CMB);
5218
5219 // Draw some flying sprites onto dest
5220
1/2
✓ Branch 0 taken 16129780 times.
✗ Branch 1 not taken.
16129780 clear_clip_rect(dest);
5221
5/6
✓ Branch 0 taken 16084154 times.
✓ Branch 1 taken 45626 times.
✓ Branch 2 taken 6328 times.
✓ Branch 3 taken 16077826 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 6328 times.
16129780 if (!is_extended_height_mode() && is_in_scrolling_region() && !get_qr(qr_SUBSCREENOVERSPRITES))
5222 add_clip_rect(dest, 0, playing_field_offset, dest->w, dest->h);
5223
5224
2/2
✓ Branch 0 taken 16126850 times.
✓ Branch 1 taken 2930 times.
16129780 if (classic_draw)
5225 {
5226 //Jumping Hero and jumping enemies are drawn on this layer.
5227
5/8
✓ Branch 0 taken 16126850 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 16126850 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 16126850 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 14064 times.
✓ Branch 7 taken 16112786 times.
16126850 if(Hero.getZ() > (zfix)zinit.jump_hero_layer_threshold)
5228 {
5229
1/2
✓ Branch 0 taken 14064 times.
✗ Branch 1 not taken.
14064 decorations.draw2(dest,false);
5230
1/2
✓ Branch 0 taken 14064 times.
✗ Branch 1 not taken.
14064 Hero.draw(dest);
5231
1/2
✓ Branch 0 taken 14064 times.
✗ Branch 1 not taken.
14064 chainlinks.draw(dest,true);
5232
1/2
✓ Branch 0 taken 14064 times.
✗ Branch 1 not taken.
14064 do_primitives(dest, SPLAYER_CHAINLINK_DRAW);
5233
5234
3/4
✓ Branch 0 taken 16806 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2742 times.
✓ Branch 3 taken 14064 times.
16806 for(int32_t i=0; i<Lwpns.Count(); i++)
5235 {
5236
9/16
✓ Branch 0 taken 2742 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2742 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2742 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 2742 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 2742 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 2742 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 2742 times.
✗ Branch 13 not taken.
✓ Branch 14 taken 239 times.
✓ Branch 15 taken 2503 times.
2742 if(Lwpns.spr(i)->z+Lwpns.spr(i)->fakez > (zfix)zinit.jump_hero_layer_threshold)
5237 {
5238
2/4
✓ Branch 0 taken 239 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 239 times.
✗ Branch 3 not taken.
239 Lwpns.spr(i)->draw(dest);
5239 239 }
5240 2742 }
5241
1/2
✓ Branch 0 taken 14064 times.
✗ Branch 1 not taken.
14064 do_primitives(dest, SPLAYER_LWEAP_ABOVE_DRAW);
5242
5243
1/2
✓ Branch 0 taken 14064 times.
✗ Branch 1 not taken.
14064 decorations.draw(dest,false);
5244 14064 }
5245
5246
5/6
✓ Branch 0 taken 3872571 times.
✓ Branch 1 taken 12254279 times.
✓ Branch 2 taken 44337870 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 32083591 times.
✓ Branch 5 taken 12254279 times.
48210441 if(!get_qr(qr_ENEMIESZAXIS)) for(int32_t i=0; i<guys.Count(); i++)
5247 {
5248
13/22
✓ Branch 0 taken 32083591 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 32083591 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 27177493 times.
✓ Branch 5 taken 4906098 times.
✓ Branch 6 taken 27177493 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 27177493 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 27177493 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 27177493 times.
✗ Branch 13 not taken.
✓ Branch 14 taken 27177493 times.
✗ Branch 15 not taken.
✓ Branch 16 taken 27177493 times.
✗ Branch 17 not taken.
✓ Branch 18 taken 27177493 times.
✗ Branch 19 not taken.
✓ Branch 20 taken 6568 times.
✓ Branch 21 taken 27170925 times.
32083591 if((isflier(guys.spr(i)->id)) || (guys.spr(i)->z+guys.spr(i)->fakez) > (zfix)zinit.jump_hero_layer_threshold)
5249 {
5250
2/4
✓ Branch 0 taken 4912666 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4912666 times.
✗ Branch 3 not taken.
4912666 guys.spr(i)->draw(dest);
5251 4912666 }
5252 44337870 }
5253 else
5254 {
5255
3/4
✓ Branch 0 taken 12206548 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 8333977 times.
✓ Branch 3 taken 3872571 times.
12206548 for(int32_t i=0; i<guys.Count(); i++)
5256 {
5257
13/22
✓ Branch 0 taken 8333977 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 8333977 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 6997572 times.
✓ Branch 5 taken 1336405 times.
✓ Branch 6 taken 6997572 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 6997572 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 6997572 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 6478745 times.
✓ Branch 13 taken 518827 times.
✓ Branch 14 taken 6478745 times.
✗ Branch 15 not taken.
✓ Branch 16 taken 6478745 times.
✗ Branch 17 not taken.
✓ Branch 18 taken 6478745 times.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✓ Branch 21 taken 6478745 times.
8333977 if((isflier(guys.spr(i)->id)) || guys.spr(i)->z > 0 || guys.spr(i)->fakez > 0)
5258 {
5259
2/4
✓ Branch 0 taken 1855232 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1855232 times.
✗ Branch 3 not taken.
1855232 guys.spr(i)->draw(dest);
5260 1855232 }
5261 8333977 }
5262 }
5263
1/2
✓ Branch 0 taken 16126850 times.
✗ Branch 1 not taken.
16126850 do_primitives(dest, SPLAYER_NPC_AIRBORNE_DRAW);
5264 16126850 }
5265
1/2
✓ Branch 0 taken 2930 times.
✗ Branch 1 not taken.
2930 else draw_sprites(dest, sorted_sprites, sprite_it, zinit.sprite_z_thresholds[SPRITE_THRESHOLD_OVERHEAD]);
5266
5267 // Draw the Moving Fairy above layer 3
5268
3/4
✓ Branch 0 taken 19453046 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3323266 times.
✓ Branch 3 taken 16129780 times.
19453046 for(int32_t i=0; i<items.Count(); i++)
5269
6/8
✓ Branch 0 taken 3323266 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 70250 times.
✓ Branch 3 taken 3253016 times.
✓ Branch 4 taken 70250 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 60536 times.
✓ Branch 7 taken 9714 times.
3383802 if(itemsbuf[items.spr(i)->id].type == itype_fairy && itemsbuf[items.spr(i)->id].misc3)
5270
2/4
✓ Branch 0 taken 60536 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 60536 times.
✗ Branch 3 not taken.
60536 items.spr(i)->draw(dest);
5271
1/2
✓ Branch 0 taken 16129780 times.
✗ Branch 1 not taken.
16129780 do_primitives(dest, SPLAYER_FAIRYITEM_DRAW);
5272
5273 // Draw some layers onto dest
5274
5275
1/2
✓ Branch 0 taken 16129780 times.
✗ Branch 1 not taken.
16129780 set_draw_screen_clip(dest);
5276
5277
2/2
✓ Branch 0 taken 16115428 times.
✓ Branch 1 taken 14352 times.
16129780 if (lightbeam_present)
5278 {
5279 14352 color_map = &trans_table2;
5280
2/2
✓ Branch 0 taken 13114 times.
✓ Branch 1 taken 1238 times.
14352 if(get_qr(qr_LIGHTBEAM_TRANSPARENT))
5281
1/2
✓ Branch 0 taken 13114 times.
✗ Branch 1 not taken.
13114 draw_trans_sprite(dest, lightbeam_bmp, 0, playing_field_offset);
5282 else
5283
1/2
✓ Branch 0 taken 1238 times.
✗ Branch 1 not taken.
1238 masked_blit(lightbeam_bmp, dest, 0, 0, 0, playing_field_offset, 256, 176);
5284 14352 color_map = &trans_table;
5285 14352 }
5286
5287
1/2
✓ Branch 0 taken 16129780 times.
✗ Branch 1 not taken.
32395878 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
5288 16266098 do_layer(dest, 0, screen_handles[5], offx, offy);
5289 16266098 });
5290
5291
2/2
✓ Branch 0 taken 2930 times.
✓ Branch 1 taken 16126850 times.
16129780 if (!classic_draw)
5292
1/2
✓ Branch 0 taken 2930 times.
✗ Branch 1 not taken.
2930 draw_sprites(dest, sorted_sprites, sprite_it, zinit.sprite_z_thresholds[SPRITE_THRESHOLD_5]);
5293
5294
1/2
✓ Branch 0 taken 16129780 times.
✗ Branch 1 not taken.
16129780 do_layer_primitives(dest, 5);
5295
1/2
✓ Branch 0 taken 16129780 times.
✗ Branch 1 not taken.
16129780 particles.draw(dest, true, 5);
5296
1/2
✓ Branch 0 taken 16129780 times.
✗ Branch 1 not taken.
16129780 _do_current_ffc_layer(dest, 5);
5297
1/2
✓ Branch 0 taken 16129780 times.
✗ Branch 1 not taken.
16129780 draw_msgstr(5);
5298
5299
1/2
✓ Branch 0 taken 16129780 times.
✗ Branch 1 not taken.
16129780 _do_current_ffc_layer(dest, -1000); // 'overhead' freeform combos
5300
5301
1/2
✓ Branch 0 taken 16129780 times.
✗ Branch 1 not taken.
16129780 do_primitives(dest, SPLAYER_OVERHEAD_FFC);
5302
5303
1/2
✓ Branch 0 taken 16129780 times.
✗ Branch 1 not taken.
32395878 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
5304 16266098 do_layer(dest, 0, screen_handles[6], offx, offy);
5305 16266098 });
5306
5307
2/2
✓ Branch 0 taken 2930 times.
✓ Branch 1 taken 16126850 times.
16129780 if (!classic_draw)
5308
1/2
✓ Branch 0 taken 2930 times.
✗ Branch 1 not taken.
2930 draw_sprites(dest, sorted_sprites, sprite_it, word(-1));
5309
5310
1/2
✓ Branch 0 taken 16129780 times.
✗ Branch 1 not taken.
16129780 do_layer_primitives(dest, 6);
5311
1/2
✓ Branch 0 taken 16129780 times.
✗ Branch 1 not taken.
16129780 particles.draw(dest, true, 6);
5312
1/2
✓ Branch 0 taken 16129780 times.
✗ Branch 1 not taken.
16129780 _do_current_ffc_layer(dest, 6);
5313
5314 16129780 bool any_dark = false;
5315
1/2
✓ Branch 0 taken 16129780 times.
✗ Branch 1 not taken.
32395878 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
5316 16266098 mapscr* base_scr = screen_handles[0].scr;
5317 16266098 any_dark |= is_dark(base_scr);
5318 16266098 });
5319
5320 // Handle low drawn darkness
5321
4/4
✓ Branch 0 taken 1859567 times.
✓ Branch 1 taken 14270213 times.
✓ Branch 2 taken 1512668 times.
✓ Branch 3 taken 346899 times.
16129780 if(get_qr(qr_NEW_DARKROOM) && any_dark)
5322 {
5323
1/2
✓ Branch 0 taken 346899 times.
✗ Branch 1 not taken.
700032 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
5324 353133 mapscr* base_scr = screen_handles[0].scr;
5325 353133 calc_darkroom_combos(base_scr, offx, offy + playing_field_offset);
5326 353133 calc_darkroom_ffcs(base_scr, 0, playing_field_offset);
5327 353133 });
5328
1/2
✓ Branch 0 taken 346899 times.
✗ Branch 1 not taken.
346899 if(showhero)
5329
1/2
✓ Branch 0 taken 346899 times.
✗ Branch 1 not taken.
346899 Hero.calc_darkroom_hero(0, -playing_field_offset);
5330
1/2
✓ Branch 0 taken 346899 times.
✗ Branch 1 not taken.
700032 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
5331 353133 mapscr* base_scr = screen_handles[0].scr;
5332
2/2
✓ Branch 0 taken 348403 times.
✓ Branch 1 taken 4730 times.
353133 if (!is_dark(base_scr))
5333 {
5334 4730 offy += playing_field_offset;
5335 4730 rectfill(darkscr_bmp, offx - viewport.x, offy - viewport.y, offx - viewport.x + 256 - 1, offy - viewport.y + 176 - 1, 0);
5336 4730 rectfill(darkscr_bmp_trans, offx - viewport.x, offy - viewport.y, offx - viewport.x + 256 - 1, offy - viewport.y + 176 - 1, 0);
5337 4730 }
5338 353133 });
5339 346899 }
5340
5341 //Darkroom if under the subscreen
5342
6/6
✓ Branch 0 taken 1859567 times.
✓ Branch 1 taken 14270213 times.
✓ Branch 2 taken 1409427 times.
✓ Branch 3 taken 450140 times.
✓ Branch 4 taken 334908 times.
✓ Branch 5 taken 1074519 times.
16129780 if(get_qr(qr_NEW_DARKROOM) && get_qr(qr_NEWDARK_L6) && any_dark)
5343 {
5344
1/2
✓ Branch 0 taken 334908 times.
✗ Branch 1 not taken.
334908 do_primitives(dest, SPLAYER_DARKROOM_UNDER);
5345
1/2
✓ Branch 0 taken 334908 times.
✗ Branch 1 not taken.
334908 set_clip_rect(dest, 0, playing_field_offset, dest->w, dest->h);
5346
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 334908 times.
334908 if(hero_scr->flags9 & fDARK_DITHER) //dither the entire bitmap
5347 {
5348 ditherblit(darkscr_bmp,darkscr_bmp,0,game->get_dither_type(),game->get_dither_arg());
5349 ditherblit(darkscr_bmp_trans,darkscr_bmp_trans,0,game->get_dither_type(),game->get_dither_arg());
5350 }
5351
5352 334908 color_map = &trans_table2;
5353
2/2
✓ Branch 0 taken 15523 times.
✓ Branch 1 taken 319385 times.
334908 if(hero_scr->flags9 & fDARK_TRANS) //draw the dark as transparent
5354 {
5355
1/2
✓ Branch 0 taken 15523 times.
✗ Branch 1 not taken.
15523 draw_trans_sprite(dest, darkscr_bmp, 0, 0);
5356
1/2
✓ Branch 0 taken 15523 times.
✗ Branch 1 not taken.
15523 if(get_qr(qr_NEWDARK_TRANS_STACKING))
5357
1/2
✓ Branch 0 taken 15523 times.
✗ Branch 1 not taken.
15523 draw_trans_sprite(dest, darkscr_bmp_trans, 0, 0);
5358 15523 }
5359 else
5360 {
5361
1/2
✓ Branch 0 taken 319385 times.
✗ Branch 1 not taken.
319385 masked_blit(darkscr_bmp, dest, 0, 0, 0, 0, dest->w, dest->h);
5362
1/2
✓ Branch 0 taken 319385 times.
✗ Branch 1 not taken.
319385 draw_trans_sprite(dest, darkscr_bmp_trans, 0, 0);
5363 }
5364 334908 color_map = &trans_table;
5365
5366
1/2
✓ Branch 0 taken 334908 times.
✗ Branch 1 not taken.
334908 set_clip_rect(dest, 0, 0, dest->w, dest->h);
5367
1/2
✓ Branch 0 taken 334908 times.
✗ Branch 1 not taken.
334908 do_primitives(dest, SPLAYER_DARKROOM_OVER);
5368 334908 }
5369
5370
3/6
✓ Branch 0 taken 51954 times.
✓ Branch 1 taken 16077826 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 51954 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
16129780 if (is_in_scrolling_region() && lensclk && !FFCore.system_suspend[susptLENS])
5371 {
5372 draw_lens_over(dest);
5373 --lensclk;
5374 }
5375
5376 // Draw some text on dest
5377
5378
1/2
✓ Branch 0 taken 16129780 times.
✗ Branch 1 not taken.
16129780 set_clip_rect(dest,0,0,256,232);
5379
5380
1/2
✓ Branch 0 taken 16129780 times.
✗ Branch 1 not taken.
16129780 if(!get_qr(qr_LAYER6_STRINGS_OVER_SUBSCREEN))
5381
1/2
✓ Branch 0 taken 16129780 times.
✗ Branch 1 not taken.
16129780 draw_msgstr(6);
5382
5383 // Draw the subscreen, without clipping
5384
2/2
✓ Branch 0 taken 6878396 times.
✓ Branch 1 taken 9251384 times.
16129780 if(get_qr(qr_SUBSCREENOVERSPRITES))
5385 {
5386
2/2
✓ Branch 0 taken 42256 times.
✓ Branch 1 taken 6836140 times.
6878396 if (drawPassiveSubscreenSeparate)
5387
1/2
✓ Branch 0 taken 42256 times.
✗ Branch 1 not taken.
42256 blit(dest, framebuf_no_passive_subscreen, 0, 0, 0, 0, dest->w, dest->h);
5388
5389
2/4
✓ Branch 0 taken 6878396 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 6878396 times.
✗ Branch 3 not taken.
6878396 put_passive_subscr(dest, 0, 0, game->should_show_time(), sspUP);
5390
5391
1/2
✓ Branch 0 taken 6878396 times.
✗ Branch 1 not taken.
6878396 do_primitives(dest, 7);
5392
2/2
✓ Branch 0 taken 42256 times.
✓ Branch 1 taken 6836140 times.
6878396 if (drawPassiveSubscreenSeparate)
5393
1/2
✓ Branch 0 taken 42256 times.
✗ Branch 1 not taken.
42256 do_primitives(framebuf_no_passive_subscreen, 7);
5394 6878396 }
5395
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 9251384 times.
9251384 else if (!classic_draw)
5396 do_primitives(dest, 7);
5397
5398
1/2
✓ Branch 0 taken 16129780 times.
✗ Branch 1 not taken.
16129780 draw_screen_post_passive_subscreen(dest, any_dark);
5399
2/2
✓ Branch 0 taken 42256 times.
✓ Branch 1 taken 16087524 times.
16129780 if (drawPassiveSubscreenSeparate)
5400
1/2
✓ Branch 0 taken 42256 times.
✗ Branch 1 not taken.
42256 draw_screen_post_passive_subscreen(framebuf_no_passive_subscreen, any_dark);
5401
5402
2/2
✓ Branch 0 taken 15628236 times.
✓ Branch 1 taken 31758016 times.
16129780 set_clip_rect(scrollbuf, 0, 0, scrollbuf->w, scrollbuf->h);
5403
3/4
✓ Branch 0 taken 15516209 times.
✓ Branch 1 taken 158875 times.
✓ Branch 2 taken 15516209 times.
✗ Branch 3 not taken.
15628236 if(runGeneric) FFCore.runGenericPassiveEngine(SCR_TIMING_POST_DRAW);
5404
5405
2/2
✓ Branch 0 taken 1931 times.
✓ Branch 1 taken 15675084 times.
15677015 for(sprite* spr : temp_sprites)
5406
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1931 times.
1931 delete spr;
5407 79191116 }
5408
5409 // TODO: separate setting door data and drawing door
5410 28153 void put_door(mapscr* scr, BITMAP *dest, int32_t pos, int32_t side, int32_t type, bool redraw, bool even_walls)
5411 {
5412
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 28153 times.
28153 if (type > 8) return;
5413
5414 28153 int32_t d=scr->door_combo_set;
5415
5416
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 15611 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 12542 times.
28153 switch(type)
5417 {
5418 case dt_wall:
5419 case dt_walk:
5420 if(!even_walls)
5421 break;
5422 [[fallthrough]];
5423 case dt_pass:
5424
3/4
✓ Branch 0 taken 1036 times.
✓ Branch 1 taken 11506 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1036 times.
12542 if(!get_qr(qr_REPLACEOPENDOORS) && !even_walls)
5425 1036 break;
5426 [[fallthrough]];
5427 case dt_lock:
5428 case dt_shut:
5429 case dt_boss:
5430 case dt_olck:
5431 case dt_osht:
5432 case dt_obos:
5433 case dt_bomb:
5434
4/5
✗ Branch 0 not taken.
✓ Branch 1 taken 7259 times.
✓ Branch 2 taken 6784 times.
✓ Branch 3 taken 6362 times.
✓ Branch 4 taken 6712 times.
27117 switch(side)
5435 {
5436 case up:
5437 7259 scr->data[pos] = DoorComboSets[d].doorcombo_u[type][0];
5438 7259 scr->cset[pos] = DoorComboSets[d].doorcset_u[type][0];
5439 7259 scr->sflag[pos] = 0;
5440 7259 scr->data[pos+1] = DoorComboSets[d].doorcombo_u[type][1];
5441 7259 scr->cset[pos+1] = DoorComboSets[d].doorcset_u[type][1];
5442 7259 scr->sflag[pos+1] = 0;
5443 7259 scr->data[pos+16] = DoorComboSets[d].doorcombo_u[type][2];
5444 7259 scr->cset[pos+16] = DoorComboSets[d].doorcset_u[type][2];
5445 7259 scr->sflag[pos+16] = 0;
5446 7259 scr->data[pos+16+1] = DoorComboSets[d].doorcombo_u[type][3];
5447 7259 scr->cset[pos+16+1] = DoorComboSets[d].doorcset_u[type][3];
5448 7259 scr->sflag[pos+16+1] = 0;
5449
5450
2/2
✓ Branch 0 taken 5435 times.
✓ Branch 1 taken 1824 times.
7259 if(redraw)
5451 {
5452 3648 putcombo(dest,(pos&15)<<4,pos&0xF0,
5453 1824 DoorComboSets[d].doorcombo_u[type][0],
5454 1824 DoorComboSets[d].doorcset_u[type][0]);
5455 3648 putcombo(dest,((pos&15)<<4)+16,pos&0xF0,
5456 1824 DoorComboSets[d].doorcombo_u[type][1],
5457 1824 DoorComboSets[d].doorcset_u[type][1]);
5458 1824 }
5459
5460 7259 break;
5461
5462 case down:
5463 6784 scr->data[pos] = DoorComboSets[d].doorcombo_d[type][0];
5464 6784 scr->cset[pos] = DoorComboSets[d].doorcset_d[type][0];
5465 6784 scr->sflag[pos] = 0;
5466 6784 scr->data[pos+1] = DoorComboSets[d].doorcombo_d[type][1];
5467 6784 scr->cset[pos+1] = DoorComboSets[d].doorcset_d[type][1];
5468 6784 scr->sflag[pos+1] = 0;
5469 6784 scr->data[pos+16] = DoorComboSets[d].doorcombo_d[type][2];
5470 6784 scr->cset[pos+16] = DoorComboSets[d].doorcset_d[type][2];
5471 6784 scr->sflag[pos+16] = 0;
5472 6784 scr->data[pos+16+1] = DoorComboSets[d].doorcombo_d[type][3];
5473 6784 scr->cset[pos+16+1] = DoorComboSets[d].doorcset_d[type][3];
5474 6784 scr->sflag[pos+16+1] = 0;
5475
5476
2/2
✓ Branch 0 taken 5463 times.
✓ Branch 1 taken 1321 times.
6784 if(redraw)
5477 {
5478 2642 putcombo(dest,(pos&15)<<4,(pos&0xF0)+16,
5479 1321 DoorComboSets[d].doorcombo_d[type][2],
5480 1321 DoorComboSets[d].doorcset_d[type][2]);
5481 2642 putcombo(dest,((pos&15)<<4)+16,(pos&0xF0)+16,
5482 1321 DoorComboSets[d].doorcombo_d[type][3],
5483 1321 DoorComboSets[d].doorcset_d[type][3]);
5484 1321 }
5485
5486 6784 break;
5487
5488 case left:
5489 6362 scr->data[pos] = DoorComboSets[d].doorcombo_l[type][0];
5490 6362 scr->cset[pos] = DoorComboSets[d].doorcset_l[type][0];
5491 6362 scr->sflag[pos] = 0;
5492 6362 scr->data[pos+1] = DoorComboSets[d].doorcombo_l[type][1];
5493 6362 scr->cset[pos+1] = DoorComboSets[d].doorcset_l[type][1];
5494 6362 scr->sflag[pos+1] = 0;
5495 6362 scr->data[pos+16] = DoorComboSets[d].doorcombo_l[type][2];
5496 6362 scr->cset[pos+16] = DoorComboSets[d].doorcset_l[type][2];
5497 6362 scr->sflag[pos+16] = 0;
5498 6362 scr->data[pos+16+1] = DoorComboSets[d].doorcombo_l[type][3];
5499 6362 scr->cset[pos+16+1] = DoorComboSets[d].doorcset_l[type][3];
5500 6362 scr->sflag[pos+16+1] = 0;
5501 6362 scr->data[pos+32] = DoorComboSets[d].doorcombo_l[type][4];
5502 6362 scr->cset[pos+32] = DoorComboSets[d].doorcset_l[type][4];
5503 6362 scr->sflag[pos+32] = 0;
5504 6362 scr->data[pos+32+1] = DoorComboSets[d].doorcombo_l[type][5];
5505 6362 scr->cset[pos+32+1] = DoorComboSets[d].doorcset_l[type][5];
5506 6362 scr->sflag[pos+32+1] = 0;
5507
5508
2/2
✓ Branch 0 taken 4873 times.
✓ Branch 1 taken 1489 times.
6362 if(redraw)
5509 {
5510 2978 putcombo(dest,(pos&15)<<4,pos&0xF0,
5511 1489 DoorComboSets[d].doorcombo_l[type][0],
5512 1489 DoorComboSets[d].doorcset_l[type][0]);
5513 2978 putcombo(dest,(pos&15)<<4,(pos&0xF0)+16,
5514 1489 DoorComboSets[d].doorcombo_l[type][2],
5515 1489 DoorComboSets[d].doorcset_l[type][2]);
5516 2978 putcombo(dest,(pos&15)<<4,(pos&0xF0)+32,
5517 1489 DoorComboSets[d].doorcombo_l[type][4],
5518 1489 DoorComboSets[d].doorcset_l[type][4]);
5519 1489 }
5520
5521 6362 break;
5522
5523 case right:
5524 6712 scr->data[pos] = DoorComboSets[d].doorcombo_r[type][0];
5525 6712 scr->cset[pos] = DoorComboSets[d].doorcset_r[type][0];
5526 6712 scr->sflag[pos] = 0;
5527 6712 scr->data[pos+1] = DoorComboSets[d].doorcombo_r[type][1];
5528 6712 scr->cset[pos+1] = DoorComboSets[d].doorcset_r[type][1];
5529 6712 scr->sflag[pos+1] = 0;
5530 6712 scr->data[pos+16] = DoorComboSets[d].doorcombo_r[type][2];
5531 6712 scr->cset[pos+16] = DoorComboSets[d].doorcset_r[type][2];
5532 6712 scr->sflag[pos+16] = 0;
5533 6712 scr->data[pos+16+1] = DoorComboSets[d].doorcombo_r[type][3];
5534 6712 scr->cset[pos+16+1] = DoorComboSets[d].doorcset_r[type][3];
5535 6712 scr->sflag[pos+16+1] = 0;
5536 6712 scr->data[pos+32] = DoorComboSets[d].doorcombo_r[type][4];
5537 6712 scr->cset[pos+32] = DoorComboSets[d].doorcset_r[type][4];
5538 6712 scr->sflag[pos+32] = 0;
5539 6712 scr->data[pos+32+1] = DoorComboSets[d].doorcombo_r[type][5];
5540 6712 scr->cset[pos+32+1] = DoorComboSets[d].doorcset_r[type][5];
5541 6712 scr->sflag[pos+32+1] = 0;
5542
5543
2/2
✓ Branch 0 taken 5058 times.
✓ Branch 1 taken 1654 times.
6712 if(redraw)
5544 {
5545 3308 putcombo(dest,(pos&15)<<4,pos&0xF0,
5546 1654 DoorComboSets[d].doorcombo_r[type][0],
5547 1654 DoorComboSets[d].doorcset_r[type][0]);
5548 3308 putcombo(dest,(pos&15)<<4,(pos&0xF0)+16,
5549 1654 DoorComboSets[d].doorcombo_r[type][2],
5550 1654 DoorComboSets[d].doorcset_r[type][2]);
5551 3308 putcombo(dest,(pos&15)<<4,(pos&0xF0)+32,
5552 1654 DoorComboSets[d].doorcombo_r[type][4],
5553 1654 DoorComboSets[d].doorcset_r[type][4]);
5554 1654 }
5555
5556 6712 break;
5557 }
5558
5559 27117 break;
5560
5561 default:
5562 break;
5563 }
5564 28153 }
5565
5566 706556 static void over_door(mapscr* scr, BITMAP *dest, int32_t pos, int32_t side, int32_t offx, int32_t offy)
5567 {
5568 706556 int32_t door_combo_set = scr->door_combo_set;
5569 706556 int32_t x = (pos&15)<<4;
5570 706556 int32_t y = (pos&0xF0);
5571 706556 int32_t d = door_combo_set;
5572 706556 x += offx;
5573 706556 y += offy;
5574
5575
4/5
✗ Branch 0 not taken.
✓ Branch 1 taken 161136 times.
✓ Branch 2 taken 179643 times.
✓ Branch 3 taken 196353 times.
✓ Branch 4 taken 169424 times.
706556 switch(side)
5576 {
5577 case up:
5578 322272 overcombo2(dest,x,y,
5579 161136 DoorComboSets[d].bombdoorcombo_u[0],
5580 161136 DoorComboSets[d].bombdoorcset_u[0]);
5581 322272 overcombo2(dest,x+16,y,
5582 161136 DoorComboSets[d].bombdoorcombo_u[1],
5583 161136 DoorComboSets[d].bombdoorcset_u[1]);
5584 161136 break;
5585
5586 case down:
5587 359286 overcombo2(dest,x,y,
5588 179643 DoorComboSets[d].bombdoorcombo_d[0],
5589 179643 DoorComboSets[d].bombdoorcset_d[0]);
5590 359286 overcombo2(dest,x+16,y,
5591 179643 DoorComboSets[d].bombdoorcombo_d[1],
5592 179643 DoorComboSets[d].bombdoorcset_d[1]);
5593 179643 break;
5594
5595 case left:
5596 392706 overcombo2(dest,x,y,
5597 196353 DoorComboSets[d].bombdoorcombo_l[0],
5598 196353 DoorComboSets[d].bombdoorcset_l[0]);
5599 392706 overcombo2(dest,x,y+16,
5600 196353 DoorComboSets[d].bombdoorcombo_l[1],
5601 196353 DoorComboSets[d].bombdoorcset_l[1]);
5602 392706 overcombo2(dest,x,y+16,
5603 196353 DoorComboSets[d].bombdoorcombo_l[2],
5604 196353 DoorComboSets[d].bombdoorcset_l[2]);
5605 196353 break;
5606
5607 case right:
5608 338848 overcombo2(dest,x,y,
5609 169424 DoorComboSets[d].bombdoorcombo_r[0],
5610 169424 DoorComboSets[d].bombdoorcset_r[0]);
5611 338848 overcombo2(dest,x,y+16,
5612 169424 DoorComboSets[d].bombdoorcombo_r[1],
5613 169424 DoorComboSets[d].bombdoorcset_r[1]);
5614 338848 overcombo2(dest,x,y+16,
5615 169424 DoorComboSets[d].bombdoorcombo_r[2],
5616 169424 DoorComboSets[d].bombdoorcset_r[2]);
5617 169424 break;
5618 }
5619 706556 }
5620
5621 47568 void update_door(mapscr* scr, int32_t side, int32_t door, bool even_walls)
5622 {
5623
7/8
✓ Branch 0 taken 47460 times.
✓ Branch 1 taken 108 times.
✓ Branch 2 taken 47460 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 22925 times.
✓ Branch 5 taken 24535 times.
✓ Branch 6 taken 530 times.
✓ Branch 7 taken 22395 times.
47568 if(door == dNONE || (!even_walls&&(door==dWALL||door==dWALK)))
5624 25173 return;
5625
5626 int32_t doortype;
5627
5628
10/12
✓ Branch 0 taken 522 times.
✓ Branch 1 taken 655 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 12492 times.
✓ Branch 5 taken 910 times.
✓ Branch 6 taken 1553 times.
✓ Branch 7 taken 3192 times.
✓ Branch 8 taken 1694 times.
✓ Branch 9 taken 172 times.
✓ Branch 10 taken 67 times.
✓ Branch 11 taken 1138 times.
22395 switch(door)
5629 {
5630 case dWALL:
5631 doortype=dt_wall;
5632 break;
5633
5634 case dWALK:
5635 doortype=dt_walk;
5636 break;
5637
5638 case dOPEN:
5639 12492 doortype=dt_pass;
5640 12492 break;
5641
5642 case dLOCKED:
5643 910 doortype=dt_lock;
5644 910 break;
5645
5646 case dUNLOCKED:
5647 1553 doortype=dt_olck;
5648 1553 break;
5649
5650 case dSHUTTER:
5651
3/4
✓ Branch 0 taken 2783 times.
✓ Branch 1 taken 409 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2783 times.
3192 if(screenscrolling && ((HeroDir()^1)==side))
5652 {
5653 doortype=dt_osht;
5654 get_screen_state(scr->screen).open_doors = -4;
5655 break;
5656 }
5657
5658 [[fallthrough]];
5659 case d1WAYSHUTTER:
5660 3714 doortype=dt_shut;
5661 3714 break;
5662
5663 case dOPENSHUTTER:
5664 1694 doortype=dt_osht;
5665 1694 break;
5666
5667 case dBOSS:
5668 172 doortype=dt_boss;
5669 172 break;
5670
5671 case dOPENBOSS:
5672 67 doortype=dt_obos;
5673 67 break;
5674
5675 case dBOMBED:
5676 1138 doortype=dt_bomb;
5677 1138 break;
5678
5679 default:
5680 655 return;
5681 }
5682
5683
4/5
✗ Branch 0 not taken.
✓ Branch 1 taken 5629 times.
✓ Branch 2 taken 5770 times.
✓ Branch 3 taken 5111 times.
✓ Branch 4 taken 5230 times.
21740 switch(side)
5684 {
5685 case up:
5686 5629 put_door(scr,nullptr,7,side,doortype,false,even_walls);
5687 5629 break;
5688
5689 case down:
5690 5770 put_door(scr,nullptr,151,side,doortype,false,even_walls);
5691 5770 break;
5692
5693 case left:
5694 5111 put_door(scr,nullptr,64,side,doortype,false,even_walls);
5695 5111 break;
5696
5697 case right:
5698 5230 put_door(scr,nullptr,78,side,doortype,false,even_walls);
5699 5230 break;
5700 }
5701 47568 }
5702
5703 6504 void putdoor(mapscr* scr, BITMAP *dest, int32_t side, int32_t door, bool redraw, bool even_walls)
5704 {
5705 /*
5706 #define dWALL 0 // 000 0
5707 #define dBOMB 6 // 011 0
5708 #define 8 // 100 0
5709 enum {dt_pass=0, dt_lock, dt_shut, dt_boss, dt_olck, dt_osht, dt_obos, dt_wall, dt_bomb, dt_walk, dt_max};
5710 */
5711
5712
7/8
✓ Branch 0 taken 6504 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 6500 times.
✓ Branch 3 taken 4 times.
✓ Branch 4 taken 6417 times.
✓ Branch 5 taken 83 times.
✓ Branch 6 taken 8 times.
✓ Branch 7 taken 6409 times.
6504 if(door == dNONE || (!even_walls&&(door==dWALL||door==dWALK)))
5713 91 return;
5714
5715 int32_t doortype;
5716
5717
8/12
✓ Branch 0 taken 227 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 50 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 362 times.
✓ Branch 7 taken 1530 times.
✓ Branch 8 taken 3958 times.
✓ Branch 9 taken 4 times.
✓ Branch 10 taken 51 times.
✓ Branch 11 taken 231 times.
6413 switch(door)
5718 {
5719 case dWALL:
5720 doortype=dt_wall;
5721 break;
5722
5723 case dWALK:
5724 doortype=dt_walk;
5725 break;
5726
5727 case dOPEN:
5728 50 doortype=dt_pass;
5729 50 break;
5730
5731 case dLOCKED:
5732 doortype=dt_lock;
5733 break;
5734
5735 case dUNLOCKED:
5736 362 doortype=dt_olck;
5737 362 break;
5738
5739 case dSHUTTER:
5740
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 1530 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
1530 if(screenscrolling && ((HeroDir()^1)==side))
5741 {
5742 doortype=dt_osht;
5743 get_screen_state(cur_screen).open_doors = -4;
5744 break;
5745 }
5746
5747 [[fallthrough]];
5748 case d1WAYSHUTTER:
5749 1757 doortype=dt_shut;
5750 1757 break;
5751
5752 case dOPENSHUTTER:
5753 3958 doortype=dt_osht;
5754 3958 break;
5755
5756 case dBOSS:
5757 4 doortype=dt_boss;
5758 4 break;
5759
5760 case dOPENBOSS:
5761 51 doortype=dt_obos;
5762 51 break;
5763
5764 case dBOMBED:
5765 231 doortype=dt_bomb;
5766 231 break;
5767
5768 default:
5769 return;
5770 }
5771
5772
4/5
✗ Branch 0 not taken.
✓ Branch 1 taken 1860 times.
✓ Branch 2 taken 1357 times.
✓ Branch 3 taken 1514 times.
✓ Branch 4 taken 1682 times.
6413 switch(side)
5773 {
5774 case up:
5775
2/2
✓ Branch 0 taken 1791 times.
✓ Branch 1 taken 69 times.
1860 switch(door)
5776 {
5777 case dBOMBED:
5778
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 69 times.
138 if(redraw)
5779 {
5780 69 over_door(scr,dest,39,side,0,0);
5781 69 }
5782 [[fallthrough]];
5783 default:
5784 1860 put_door(scr,dest,7,side,doortype,redraw, even_walls);
5785 1860 break;
5786 }
5787
5788 1860 break;
5789
5790 case down:
5791
2/2
✓ Branch 0 taken 1318 times.
✓ Branch 1 taken 39 times.
1357 switch(door)
5792 {
5793 case dBOMBED:
5794
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 39 times.
78 if(redraw)
5795 {
5796 39 over_door(scr,dest,135,side,0,0);
5797 39 }
5798 [[fallthrough]];
5799 default:
5800 1357 put_door(scr,dest,151,side,doortype,redraw, even_walls);
5801 1357 break;
5802 }
5803
5804 1357 break;
5805
5806 case left:
5807
2/2
✓ Branch 0 taken 1463 times.
✓ Branch 1 taken 51 times.
1514 switch(door)
5808 {
5809 case dBOMBED:
5810
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 51 times.
102 if(redraw)
5811 {
5812 51 over_door(scr,dest,66,side,0,0);
5813 51 }
5814 [[fallthrough]];
5815 default:
5816 1514 put_door(scr,dest,64,side,doortype,redraw, even_walls);
5817 1514 break;
5818 }
5819
5820 1514 break;
5821
5822 case right:
5823
2/2
✓ Branch 0 taken 1610 times.
✓ Branch 1 taken 72 times.
1682 switch(door)
5824 {
5825 case dBOMBED:
5826
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 72 times.
144 if(redraw)
5827 {
5828 72 over_door(scr,dest,77,side,0,0);
5829 72 }
5830 [[fallthrough]];
5831 default:
5832 1682 put_door(scr,dest,78,side,doortype,redraw, even_walls);
5833 1682 break;
5834 }
5835
5836 1682 break;
5837 }
5838 6504 }
5839
5840 586 void putcombo_not_zero(BITMAP *dest, int32_t x, int32_t y, int32_t combo, int32_t cset)
5841 {
5842
1/2
✓ Branch 0 taken 586 times.
✗ Branch 1 not taken.
586 if(combo!=0)
5843 {
5844 586 putcombo(dest,x, y, combo, cset);
5845 586 }
5846 586 }
5847
5848 293 void overcombo_not_zero(BITMAP *dest, int32_t x, int32_t y, int32_t combo, int32_t cset)
5849 {
5850
2/2
✓ Branch 0 taken 219 times.
✓ Branch 1 taken 74 times.
293 if(combo!=0)
5851 {
5852 219 overcombo(dest,x, y, combo, cset);
5853 219 }
5854 293 }
5855
5856 125 void showbombeddoor(mapscr* scr, BITMAP *dest, int32_t side, int32_t offx, int32_t offy)
5857 {
5858 125 int32_t d = scr->door_combo_set;
5859
5860
4/5
✗ Branch 0 not taken.
✓ Branch 1 taken 43 times.
✓ Branch 2 taken 39 times.
✓ Branch 3 taken 6 times.
✓ Branch 4 taken 37 times.
125 switch(side)
5861 {
5862 case up:
5863 86 putcombo_not_zero(dest,((7&15)<<4) + offx,(7&0xF0) + offy,
5864 43 DoorComboSets[d].doorcombo_u[dt_bomb][0],
5865 43 DoorComboSets[d].doorcset_u[dt_bomb][0]);
5866 86 putcombo_not_zero(dest,((8&15)<<4) + offx,(8&0xF0) + offy,
5867 43 DoorComboSets[d].doorcombo_u[dt_bomb][1],
5868 43 DoorComboSets[d].doorcset_u[dt_bomb][1]);
5869 86 putcombo_not_zero(dest,((23&15)<<4) + offx,(23&0xF0) + offy,
5870 43 DoorComboSets[d].doorcombo_u[dt_bomb][2],
5871 43 DoorComboSets[d].doorcset_u[dt_bomb][2]);
5872 86 putcombo_not_zero(dest,((24&15)<<4) + offx,(24&0xF0) + offy,
5873 43 DoorComboSets[d].doorcombo_u[dt_bomb][3],
5874 43 DoorComboSets[d].doorcset_u[dt_bomb][3]);
5875 86 overcombo_not_zero(dest,((39&15)<<4) + offx,(39&0xF0) + offy,
5876 43 DoorComboSets[d].bombdoorcombo_u[0],
5877 43 DoorComboSets[d].bombdoorcset_u[0]);
5878 86 overcombo_not_zero(dest,((40&15)<<4) + offx,(40&0xF0) + offy,
5879 43 DoorComboSets[d].bombdoorcombo_u[1],
5880 43 DoorComboSets[d].bombdoorcset_u[1]);
5881 43 break;
5882
5883 case down:
5884 78 putcombo_not_zero(dest,((151&15)<<4) + offx,(151&0xF0) + offy,
5885 39 DoorComboSets[d].doorcombo_d[dt_bomb][0],
5886 39 DoorComboSets[d].doorcset_d[dt_bomb][0]);
5887 78 putcombo_not_zero(dest,((152&15)<<4) + offx,(152&0xF0) + offy,
5888 39 DoorComboSets[d].doorcombo_d[dt_bomb][1],
5889 39 DoorComboSets[d].doorcset_d[dt_bomb][1]);
5890 78 putcombo_not_zero(dest,((167&15)<<4) + offx,(167&0xF0) + offy,
5891 39 DoorComboSets[d].doorcombo_d[dt_bomb][2],
5892 39 DoorComboSets[d].doorcset_d[dt_bomb][2]);
5893 78 putcombo_not_zero(dest,((168&15)<<4) + offx,(168&0xF0) + offy,
5894 39 DoorComboSets[d].doorcombo_d[dt_bomb][3],
5895 39 DoorComboSets[d].doorcset_d[dt_bomb][3]);
5896 78 overcombo_not_zero(dest,((135&15)<<4) + offx,(135&0xF0) + offy,
5897 39 DoorComboSets[d].bombdoorcombo_d[0],
5898 39 DoorComboSets[d].bombdoorcset_d[0]);
5899 78 overcombo_not_zero(dest,((136&15)<<4) + offx,(136&0xF0) + offy,
5900 39 DoorComboSets[d].bombdoorcombo_d[1],
5901 39 DoorComboSets[d].bombdoorcset_d[1]);
5902 39 break;
5903
5904 case left:
5905 12 putcombo_not_zero(dest,((64&15)<<4) + offx,(64&0xF0) + offy,
5906 6 DoorComboSets[d].doorcombo_l[dt_bomb][0],
5907 6 DoorComboSets[d].doorcset_l[dt_bomb][0]);
5908 12 putcombo_not_zero(dest,((65&15)<<4) + offx,(65&0xF0) + offy,
5909 6 DoorComboSets[d].doorcombo_l[dt_bomb][1],
5910 6 DoorComboSets[d].doorcset_l[dt_bomb][1]);
5911 12 putcombo_not_zero(dest,((80&15)<<4) + offx,(80&0xF0) + offy,
5912 6 DoorComboSets[d].doorcombo_l[dt_bomb][2],
5913 6 DoorComboSets[d].doorcset_l[dt_bomb][2]);
5914 12 putcombo_not_zero(dest,((81&15)<<4) + offx,(81&0xF0) + offy,
5915 6 DoorComboSets[d].doorcombo_l[dt_bomb][3],
5916 6 DoorComboSets[d].doorcset_l[dt_bomb][3]);
5917 12 putcombo_not_zero(dest,((96&15)<<4) + offx,(96&0xF0) + offy,
5918 6 DoorComboSets[d].doorcombo_l[dt_bomb][4],
5919 6 DoorComboSets[d].doorcset_l[dt_bomb][4]);
5920 12 putcombo_not_zero(dest,((97&15)<<4) + offx,(97&0xF0) + offy,
5921 6 DoorComboSets[d].doorcombo_l[dt_bomb][5],
5922 6 DoorComboSets[d].doorcset_l[dt_bomb][5]);
5923 12 overcombo_not_zero(dest,((66&15)<<4) + offx,(66&0xF0) + offy,
5924 6 DoorComboSets[d].bombdoorcombo_l[0],
5925 6 DoorComboSets[d].bombdoorcset_l[0]);
5926 12 overcombo_not_zero(dest,((82&15)<<4) + offx,(82&0xF0) + offy,
5927 6 DoorComboSets[d].bombdoorcombo_l[1],
5928 6 DoorComboSets[d].bombdoorcset_l[1]);
5929 12 overcombo_not_zero(dest,((98&15)<<4) + offx,(98&0xF0) + offy,
5930 6 DoorComboSets[d].bombdoorcombo_l[2],
5931 6 DoorComboSets[d].bombdoorcset_l[2]);
5932 6 break;
5933
5934 case right:
5935 74 putcombo_not_zero(dest,((78&15)<<4) + offx,(78&0xF0) + offy,
5936 37 DoorComboSets[d].doorcombo_r[dt_bomb][0],
5937 37 DoorComboSets[d].doorcset_r[dt_bomb][0]);
5938 74 putcombo_not_zero(dest,((79&15)<<4) + offx,(79&0xF0) + offy,
5939 37 DoorComboSets[d].doorcombo_r[dt_bomb][1],
5940 37 DoorComboSets[d].doorcset_r[dt_bomb][1]);
5941 74 putcombo_not_zero(dest,((94&15)<<4) + offx,(94&0xF0) + offy,
5942 37 DoorComboSets[d].doorcombo_r[dt_bomb][2],
5943 37 DoorComboSets[d].doorcset_r[dt_bomb][2]);
5944 74 putcombo_not_zero(dest,((95&15)<<4) + offx,(95&0xF0) + offy,
5945 37 DoorComboSets[d].doorcombo_r[dt_bomb][3],
5946 37 DoorComboSets[d].doorcset_r[dt_bomb][3]);
5947 74 putcombo_not_zero(dest,((110&15)<<4) + offx,(110&0xF0) + offy,
5948 37 DoorComboSets[d].doorcombo_r[dt_bomb][4],
5949 37 DoorComboSets[d].doorcset_r[dt_bomb][4]);
5950 74 putcombo_not_zero(dest,((111&15)<<4) + offx,(111&0xF0) + offy,
5951 37 DoorComboSets[d].doorcombo_r[dt_bomb][5],
5952 37 DoorComboSets[d].doorcset_r[dt_bomb][5]);
5953 74 overcombo_not_zero(dest,((77&15)<<4) + offx,(77&0xF0) + offy,
5954 37 DoorComboSets[d].bombdoorcombo_r[0],
5955 37 DoorComboSets[d].bombdoorcset_r[0]);
5956 74 overcombo_not_zero(dest,((93&15)<<4) + offx,(93&0xF0) + offy,
5957 37 DoorComboSets[d].bombdoorcombo_r[1],
5958 37 DoorComboSets[d].bombdoorcset_r[1]);
5959 74 overcombo_not_zero(dest,((109&15)<<4) + offx,(109&0xF0) + offy,
5960 37 DoorComboSets[d].bombdoorcombo_r[2],
5961 37 DoorComboSets[d].bombdoorcset_r[2]);
5962 37 break;
5963 }
5964 125 }
5965
5966 5528664 void openshutters(mapscr* scr)
5967 {
5968 5528664 bool opened_door = false;
5969
2/2
✓ Branch 0 taken 5528664 times.
✓ Branch 1 taken 22114656 times.
27643320 for(int32_t i=0; i<4; i++)
5970
2/2
✓ Branch 0 taken 22110698 times.
✓ Branch 1 taken 3958 times.
22118614 if(scr->door[i]==dSHUTTER)
5971 {
5972 3958 putdoor(scr, scrollbuf, i, dOPENSHUTTER);
5973 3958 scr->door[i]=dOPENSHUTTER;
5974 3958 opened_door = true;
5975 3958 }
5976
5977 5528664 auto& combo_cache = combo_caches::shutter;
5978 2222215018 for_every_combo_in_screen(create_screen_handles(scr), [&](const auto& handle) {
5979
3/4
✓ Branch 0 taken 2214763753 times.
✓ Branch 1 taken 7 times.
✓ Branch 2 taken 1922594 times.
✗ Branch 3 not taken.
2216686354 if (!combo_cache.minis[handle.data()].shutter)
5980 2216686347 return;
5981
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 7 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
14 trig_each_combo_trigger(handle, [&](combo_trigger const& trig){
5982 7 return trig.trigger_flags.get(TRIGFLAG_SHUTTER);
5983 });
5984 2216686354 });
5985
5986
2/2
✓ Branch 0 taken 5525933 times.
✓ Branch 1 taken 2731 times.
5528664 if(opened_door)
5987 2731 sfx(WAV_DOOR);
5988 5528664 }
5989
5990 15711860 void clear_darkroom_bitmaps()
5991 {
5992 15711860 clear_to_color(darkscr_bmp, game->get_darkscr_color());
5993 15711860 clear_to_color(darkscr_bmp_trans, game->get_darkscr_color());
5994 15711860 }
5995
5996 16739894 bool is_dark(const mapscr* scr)
5997 {
5998 16739894 bool dark = scr->flags&fDARK;
5999
2/2
✓ Branch 0 taken 3722 times.
✓ Branch 1 taken 16736172 times.
16739894 if (region_is_lit) return !dark;
6000 16736172 return dark;
6001 16739894 }
6002
6003 53189 bool scrolling_is_dark(const mapscr* scr)
6004 {
6005 53189 bool dark = scr->flags&fDARK;
6006
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 53187 times.
53189 if (scrolling_region_is_lit) return !dark;
6007 53187 return dark;
6008 53189 }
6009
6010 38434 bool is_any_dark()
6011 {
6012 38434 bool dark = false;
6013 78124 for_every_base_screen_in_region([&](mapscr* scr, unsigned int region_scr_x, unsigned int region_scr_y) {
6014 39690 dark |= (bool)(is_dark(scr));
6015 39690 });
6016 38434 return dark;
6017 }
6018
6019
3/4
✓ Branch 0 taken 2989 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2562 times.
✓ Branch 3 taken 427 times.
2989 static mapscr prev_origin_scrs[7];
6020 427 static std::set<int> loadscr_ffc_script_ids_to_remove;
6021
6022 static void handle_screen_overlay(const std::vector<mapscr*>& screens)
6023 {
6024 mapscr* base_scr = screens[0];
6025 mapscr* previous_scr = &prev_origin_scrs[0];
6026
6027 for (int i = 0; i < 176; i++)
6028 {
6029 if (base_scr->data[i] == 0)
6030 {
6031 base_scr->data[i] = previous_scr->data[i];
6032 base_scr->sflag[i] = previous_scr->sflag[i];
6033 base_scr->cset[i] = previous_scr->cset[i];
6034 }
6035 }
6036
6037 for (int i = 0; i < 6; i++)
6038 {
6039 if (previous_scr->layermap[i] > 0 && base_scr->layermap[i] > 0)
6040 {
6041 int lm = (base_scr->layermap[i]-1)*MAPSCRS+base_scr->layerscreen[i];
6042 int fm = (previous_scr->layermap[i]-1)*MAPSCRS+previous_scr->layerscreen[i];
6043
6044 for (int j = 0; j < 176; j++)
6045 {
6046 if (TheMaps[lm].data[j] == 0)
6047 {
6048 TheMaps[lm].data[j] = TheMaps[fm].data[j];
6049 TheMaps[lm].sflag[j] = TheMaps[fm].sflag[j];
6050 TheMaps[lm].cset[j] = TheMaps[fm].cset[j];
6051 }
6052 }
6053 }
6054 }
6055
6056 for (int i = 1; i <= 6; i++)
6057 {
6058 mapscr* scr = screens[i];
6059 previous_scr = &prev_origin_scrs[i];
6060
6061 if (scr->layermap[i] > 0)
6062 {
6063 for (int y = 0; y < 11; y++)
6064 {
6065 for (int x = 0; x < 16; x++)
6066 {
6067 int c = y*16+x;
6068
6069 if (scr->data[c]==0)
6070 {
6071 scr->data[c] = previous_scr->data[c];
6072 scr->sflag[c] = previous_scr->sflag[c];
6073 scr->cset[c] = previous_scr->cset[c];
6074 }
6075 }
6076 }
6077 }
6078 }
6079 }
6080
6081 38774 static void load_a_screen_and_layers_init(int dmap, int screen, int ldir, bool screen_overlay, bool ffc_overlay)
6082 {
6083 38774 std::vector<mapscr*> screens;
6084
6085
1/2
✓ Branch 0 taken 38774 times.
✗ Branch 1 not taken.
38774 const mapscr* source = get_canonical_scr(cur_map, screen);
6086
2/4
✓ Branch 0 taken 38774 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 38774 times.
✗ Branch 3 not taken.
38774 mapscr* base_scr = new mapscr(*source);
6087 38774 temporary_screens[screen*7] = base_scr;
6088
1/2
✓ Branch 0 taken 38774 times.
✗ Branch 1 not taken.
38774 screens.push_back(base_scr);
6089
6090 38774 base_scr->valid |= mVALID; // layer 0 is always valid
6091
6092
2/2
✓ Branch 0 taken 1244 times.
✓ Branch 1 taken 37530 times.
38774 if (screen == cur_screen)
6093 37530 origin_scr = base_scr;
6094
2/2
✓ Branch 0 taken 1244 times.
✓ Branch 1 taken 37530 times.
38774 if (screen == Hero.current_screen)
6095 37530 hero_scr = prev_hero_scr = base_scr;
6096
6097
2/2
✓ Branch 0 taken 144 times.
✓ Branch 1 taken 38630 times.
38774 if (source->script > 0)
6098
1/2
✓ Branch 0 taken 144 times.
✗ Branch 1 not taken.
144 FFCore.reset_script_engine_data(ScriptType::Screen, screen);
6099
6100
2/2
✓ Branch 0 taken 38774 times.
✓ Branch 1 taken 232644 times.
271418 for (int i = 0; i < 6; i++)
6101 {
6102
2/2
✓ Branch 0 taken 176175 times.
✓ Branch 1 taken 56469 times.
232644 if(source->layermap[i]>0)
6103 {
6104
3/6
✓ Branch 0 taken 56469 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 56469 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 56469 times.
✗ Branch 5 not taken.
56469 mapscr* layer_scr = new mapscr(*get_canonical_scr(source->layermap[i]-1, source->layerscreen[i]));
6105 56469 layer_scr->map = cur_map;
6106 56469 layer_scr->screen = screen;
6107 56469 layer_scr->valid |= mVALID;
6108
1/2
✓ Branch 0 taken 56469 times.
✗ Branch 1 not taken.
56469 screens.push_back(layer_scr);
6109 56469 }
6110 else
6111 {
6112
2/4
✓ Branch 0 taken 176175 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 176175 times.
✗ Branch 3 not taken.
176175 mapscr* layer_scr = new mapscr();
6113 176175 layer_scr->map = cur_map;
6114 176175 layer_scr->screen = screen;
6115
1/2
✓ Branch 0 taken 176175 times.
✗ Branch 1 not taken.
176175 screens.push_back(layer_scr);
6116 }
6117 232644 temporary_screens[screen*7+i+1] = screens[i+1];
6118 232644 }
6119
6120
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 38774 times.
38774 if (screen_overlay)
6121 handle_screen_overlay(screens);
6122
6123
2/2
✓ Branch 0 taken 145 times.
✓ Branch 1 taken 38629 times.
38774 if (ffc_overlay)
6124 {
6125 145 mapscr* previous_scr = &prev_origin_scrs[0];
6126
1/2
✓ Branch 0 taken 145 times.
✗ Branch 1 not taken.
145 int num_ffcs = previous_scr->numFFC();
6127
2/2
✓ Branch 0 taken 4640 times.
✓ Branch 1 taken 145 times.
4785 for (int i = 0; i < num_ffcs; i++)
6128 {
6129
2/2
✓ Branch 0 taken 4365 times.
✓ Branch 1 taken 275 times.
4640 if ((previous_scr->ffcs[i].flags&ffc_carryover))
6130 {
6131
2/4
✓ Branch 0 taken 275 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 275 times.
✗ Branch 3 not taken.
275 auto& ffc = base_scr->getFFC(i) = previous_scr->ffcs[i];
6132 275 ffc.screen_spawned = screen;
6133
6134
1/2
✓ Branch 0 taken 275 times.
✗ Branch 1 not taken.
275 ffc_id_t ffc_id = get_region_screen_offset(screen)*MAXFFCS + i;
6135
1/2
✓ Branch 0 taken 275 times.
✗ Branch 1 not taken.
275 loadscr_ffc_script_ids_to_remove.erase(ffc_id);
6136
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 275 times.
275 if (previous_scr->ffcs[i].flags&ffc_scriptreset)
6137 {
6138 FFCore.reset_script_engine_data(ScriptType::FFC, ffc_id);
6139 }
6140 275 }
6141 4640 }
6142 145 }
6143
6144
1/2
✓ Branch 0 taken 38774 times.
✗ Branch 1 not taken.
1145565 auto [offx, offy] = translate_screen_coordinates_to_world(screen);
6145
1/2
✓ Branch 0 taken 38774 times.
✗ Branch 1 not taken.
38774 int num_ffcs = base_scr->numFFC();
6146
2/2
✓ Branch 0 taken 1106791 times.
✓ Branch 1 taken 38774 times.
1145565 for (word i = 0; i < num_ffcs; i++)
6147 {
6148 1106791 base_scr->ffcs[i].screen_spawned = screen;
6149
1/2
✓ Branch 0 taken 1106791 times.
✗ Branch 1 not taken.
1106791 base_scr->ffcs[i].x += offx;
6150
1/2
✓ Branch 0 taken 1106791 times.
✗ Branch 1 not taken.
1106791 base_scr->ffcs[i].y += offy;
6151 1106791 }
6152 38774 }
6153
6154 38774 static void load_a_screen_and_layers_post(int dmap, int screen, int ldir)
6155 {
6156 38774 mapscr* base_scr = get_scr(screen);
6157 38774 int mi = mapind(cur_map, screen);
6158
6159 // Apply perm secrets, if applicable.
6160
2/2
✓ Branch 0 taken 11520 times.
✓ Branch 1 taken 27254 times.
38774 if (canPermSecret(dmap, screen))
6161 {
6162
2/2
✓ Branch 0 taken 24348 times.
✓ Branch 1 taken 2906 times.
27254 if(game->maps[mi] & mSECRET) // if special stuff done before
6163 {
6164 2906 reveal_hidden_stairs(base_scr, screen, false);
6165 2906 trigger_secrets_for_screen(TriggerSource::SecretsScreenState, base_scr, false);
6166 2906 }
6167
2/2
✓ Branch 0 taken 27251 times.
✓ Branch 1 taken 3 times.
27254 if(game->maps[mi] & mLIGHTBEAM) // if special stuff done before
6168 {
6169
2/2
✓ Branch 0 taken 21 times.
✓ Branch 1 taken 3 times.
24 for (int layer = 0; layer <= 6; layer++)
6170 {
6171 21 mapscr* layer_scr = get_scr_layer(screen, layer);
6172
2/2
✓ Branch 0 taken 3696 times.
✓ Branch 1 taken 21 times.
3717 for (int pos = 0; pos < 176; pos++)
6173 {
6174 3696 newcombo const* cmb = &combobuf[layer_scr->data[pos]];
6175
2/2
✓ Branch 0 taken 3693 times.
✓ Branch 1 taken 3 times.
3696 if(cmb->type == cLIGHTTARGET)
6176 {
6177
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 if (!(cmb->usrflags&cflag1)) //Unlit version
6178 {
6179 3 layer_scr->data[pos] += 1;
6180 3 }
6181 3 }
6182 3696 }
6183 21 }
6184 3 }
6185 27254 }
6186
6187 38774 auto screen_handles = create_screen_handles(base_scr);
6188
6189 38774 int destlvl = DMaps[dmap].level;
6190 38774 toggle_switches(game->lvlswitches[destlvl], true, screen_handles);
6191 38774 toggle_gswitches_load(screen_handles);
6192
6193 38774 bool should_check_for_state_things = (screen < 0x80);
6194
2/2
✓ Branch 0 taken 907 times.
✓ Branch 1 taken 37867 times.
38774 if (should_check_for_state_things)
6195 {
6196
2/2
✓ Branch 0 taken 37433 times.
✓ Branch 1 taken 434 times.
37867 if (game->maps[mi]&mLOCKBLOCK)
6197 434 remove_lockblocks(screen_handles);
6198
2/2
✓ Branch 0 taken 37778 times.
✓ Branch 1 taken 89 times.
37867 if (game->maps[mi]&mBOSSLOCKBLOCK)
6199 89 remove_bosslockblocks(screen_handles);
6200
2/2
✓ Branch 0 taken 37699 times.
✓ Branch 1 taken 168 times.
37867 if (game->maps[mi]&mCHEST)
6201 168 remove_chests(screen_handles);
6202
1/2
✓ Branch 0 taken 37867 times.
✗ Branch 1 not taken.
37867 if (game->maps[mi]&mLOCKEDCHEST)
6203 remove_lockedchests(screen_handles);
6204
2/2
✓ Branch 0 taken 37856 times.
✓ Branch 1 taken 11 times.
37867 if (game->maps[mi]&mBOSSCHEST)
6205 11 remove_bosschests(screen_handles);
6206
6207 37867 clear_xdoors_mi(screen_handles, mi, true);
6208 37867 clear_xstatecombos_mi(screen_handles, mi, true);
6209 37867 }
6210
6211 // check doors
6212
2/2
✓ Branch 0 taken 27253 times.
✓ Branch 1 taken 11521 times.
38774 if (isdungeon(dmap, screen))
6213 {
6214
2/2
✓ Branch 0 taken 46084 times.
✓ Branch 1 taken 11521 times.
57605 for(int32_t i=0; i<4; i++)
6215 {
6216 46084 int32_t door=base_scr->door[i];
6217
6218
5/5
✓ Branch 0 taken 5303 times.
✓ Branch 1 taken 36475 times.
✓ Branch 2 taken 2372 times.
✓ Branch 3 taken 230 times.
✓ Branch 4 taken 1704 times.
46084 switch(door)
6219 {
6220 case d1WAYSHUTTER:
6221 case dSHUTTER:
6222
3/4
✓ Branch 0 taken 1694 times.
✓ Branch 1 taken 3609 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1694 times.
5303 if ((ldir^1)==i && screen == Hero.current_screen)
6223 {
6224 1694 base_scr->door[i]=dOPENSHUTTER;
6225 1694 }
6226
6227 5303 get_screen_state(screen).open_doors = -4;
6228 5303 break;
6229
6230 case dLOCKED:
6231
3/4
✓ Branch 0 taken 2372 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1473 times.
✓ Branch 3 taken 899 times.
2372 if(should_check_for_state_things && game->maps[mi]&(mDOOR_UP<<i))
6232 {
6233 1473 base_scr->door[i]=dUNLOCKED;
6234 1473 }
6235
6236 2372 break;
6237
6238 case dBOSS:
6239
3/4
✓ Branch 0 taken 230 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 62 times.
✓ Branch 3 taken 168 times.
230 if(should_check_for_state_things && game->maps[mi]&(mDOOR_UP<<i))
6240 {
6241 62 base_scr->door[i]=dOPENBOSS;
6242 62 }
6243
6244 230 break;
6245
6246 case dBOMB:
6247
3/4
✓ Branch 0 taken 1704 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1087 times.
✓ Branch 3 taken 617 times.
1704 if(should_check_for_state_things && game->maps[mi]&(mDOOR_UP<<i))
6248 {
6249 1087 base_scr->door[i]=dBOMBED;
6250 1087 }
6251
6252 1704 break;
6253 }
6254
6255 46084 update_door(base_scr, i, base_scr->door[i]);
6256
6257
4/4
✓ Branch 0 taken 41517 times.
✓ Branch 1 taken 4567 times.
✓ Branch 2 taken 736 times.
✓ Branch 3 taken 40781 times.
46084 if(door==dSHUTTER||door==d1WAYSHUTTER)
6258 {
6259 5303 base_scr->door[i]=door;
6260 5303 }
6261 46084 }
6262 11521 }
6263
6264
2/2
✓ Branch 0 taken 139 times.
✓ Branch 1 taken 38635 times.
38774 if (!(base_scr->flags3 & fCYCLEONINIT))
6265 38635 return;
6266
6267
2/2
✓ Branch 0 taken 139 times.
✓ Branch 1 taken 973 times.
1112 for (int32_t j=-1; j<6; ++j) // j == -1 denotes the current screen
6268 {
6269
4/4
✓ Branch 0 taken 834 times.
✓ Branch 1 taken 139 times.
✓ Branch 2 taken 383 times.
✓ Branch 3 taken 451 times.
973 if (j<0 || base_scr->layermap[j] > 0)
6270 {
6271 522 mapscr* layer_scr = get_scr_layer(screen, j + 1);
6272
3/4
✓ Branch 0 taken 383 times.
✓ Branch 1 taken 139 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 383 times.
522 mapscr* layerscreen= (j<0 ? base_scr : layer_scr->valid ? layer_scr :
6273 &TheMaps[(base_scr->layermap[j]-1)*MAPSCRS]+base_scr->layerscreen[j]);
6274
6275
2/2
✓ Branch 0 taken 91872 times.
✓ Branch 1 taken 522 times.
92394 for(int32_t i=0; i<176; ++i)
6276 {
6277 91872 int32_t c=layerscreen->data[i];
6278
6279 // New screen flag: Cycle Combos At Screen Init
6280
5/6
✓ Branch 0 taken 65 times.
✓ Branch 1 taken 91807 times.
✓ Branch 2 taken 29 times.
✓ Branch 3 taken 36 times.
✓ Branch 4 taken 29 times.
✗ Branch 5 not taken.
91872 if(combobuf[c].nextcombo != 0 && (j<0 || get_qr(qr_CMBCYCLELAYERS)))
6281 {
6282 65 int32_t r = 0;
6283
6284
4/4
✓ Branch 0 taken 65 times.
✓ Branch 1 taken 84 times.
✓ Branch 2 taken 84 times.
✓ Branch 3 taken 65 times.
149 while(combobuf[c].can_cycle() && r++ < 10)
6285 {
6286 84 newcombo const& cmb = combobuf[c];
6287 84 bool cycle_under = (cmb.animflags & AF_CYCLEUNDERCOMBO);
6288
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 84 times.
84 auto cid = cycle_under ? layerscreen->undercombo : cmb.nextcombo;
6289 84 layerscreen->data[i] = cid;
6290
2/2
✓ Branch 0 taken 15 times.
✓ Branch 1 taken 69 times.
84 if(!(combobuf[c].animflags & AF_CYCLENOCSET))
6291
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 69 times.
69 layerscreen->cset[i] = cycle_under ? layerscreen->undercset : cmb.nextcset;
6292 84 c = layerscreen->data[i];
6293 }
6294 65 }
6295 91872 }
6296 522 }
6297 973 }
6298 38774 }
6299
6300 // Set `cur_screen` to `screen` and load new screens into temporary memory.
6301 //
6302 // Called anytime a player moves to a new screen (either via warping, scrolling, continue, starting
6303 // the game, etc...)
6304 //
6305 // Note: for regions, only the initial screen load calls this function. Simply walking between
6306 // screens in the same region does not use this, because every screen in a region is loaded into
6307 // temporary memory up front.
6308 //
6309 // If scr >= 0x80, `Hero.current_screen` will be saved to `home_screen` and also be loaded into
6310 // `special_warp_return_scr`.
6311 //
6312 // If origin_screen_overlay is true, the old origin_scr combos will be copied to the new origin_scr combos
6313 // on all layers (but only where the new screen has a 0 combo).
6314 //
6315 // TODO: loadscr should set curdmap, but currently callers do that.
6316 37530 void loadscr(int32_t destdmap, int32_t screen, int32_t ldir, bool origin_screen_overlay, bool no_x80_dir)
6317 {
6318 37530 zapp_reporting_set_tag("screen", screen);
6319
2/2
✓ Branch 0 taken 9310 times.
✓ Branch 1 taken 28220 times.
37530 if (destdmap != -1)
6320 9310 zapp_reporting_set_tag("dmap", destdmap);
6321
6322 37530 int32_t orig_destdmap = destdmap;
6323
2/2
✓ Branch 0 taken 9310 times.
✓ Branch 1 taken 28220 times.
37530 if (destdmap < 0) destdmap = cur_dmap;
6324
6325
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 37530 times.
37530 if (replay_is_active())
6326 {
6327
2/2
✓ Branch 0 taken 28220 times.
✓ Branch 1 taken 9310 times.
37530 if (orig_destdmap != -1)
6328 {
6329
2/2
✓ Branch 0 taken 8239 times.
✓ Branch 1 taken 1071 times.
9310 if (strlen(DMaps[orig_destdmap].name) > 0)
6330 {
6331
1/2
✓ Branch 0 taken 8239 times.
✗ Branch 1 not taken.
8239 replay_step_comment(fmt::format("dmap={} {}", orig_destdmap, DMaps[orig_destdmap].name));
6332 8239 }
6333 else
6334 {
6335
1/2
✓ Branch 0 taken 1071 times.
✗ Branch 1 not taken.
1071 replay_step_comment(fmt::format("dmap={}", orig_destdmap));
6336 }
6337 9310 }
6338 37530 replay_step_comment_loadscr(screen);
6339
6340 // Reset the rngs and frame count so that recording steps can be modified without impacting
6341 // behavior of later screens.
6342 37530 replay_sync_rng();
6343 37530 }
6344
6345
2/2
✓ Branch 0 taken 1754087 times.
✓ Branch 1 taken 37530 times.
1791617 for (auto& state : get_screen_states())
6346 1754087 state.second.triggered_secrets = false;
6347 37530 slopes.clear();
6348 37530 Hero.clear_platform_ffc();
6349 37530 timeExitAllGenscript(GENSCR_ST_CHANGE_SCREEN);
6350 37530 clear_darkroom_bitmaps();
6351 37530 msgscr = nullptr;
6352
6353
2/2
✓ Branch 0 taken 52507984 times.
✓ Branch 1 taken 37530 times.
52545514 for (word x=0; x<animated_combos; x++)
6354 {
6355
2/2
✓ Branch 0 taken 21102328 times.
✓ Branch 1 taken 31405656 times.
52507984 if(combobuf[animated_combo_table4[x][0]].nextcombo!=0)
6356 {
6357 21102328 combobuf[animated_combo_table4[x][0]].aclk = 0;
6358 21102328 }
6359 52507984 }
6360 37530 reset_combo_animations2();
6361 37530 region_is_lit = false;
6362
6363 // Legacy features (combo and ffc overlays) may need the previous origin screens during loading
6364 // of the new ones.
6365 37530 bool origin_ffc_overlay = false;
6366
2/2
✓ Branch 0 taken 1170 times.
✓ Branch 1 taken 36360 times.
37530 if (origin_scr)
6367 {
6368
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 36358 times.
36360 if (!(origin_scr->flags5&fNOFFCARRYOVER))
6369 {
6370 36358 int c = origin_scr->numFFC();
6371
2/2
✓ Branch 0 taken 36213 times.
✓ Branch 1 taken 1040673 times.
1076886 for (int i = 0; i < c; i++)
6372 {
6373
2/2
✓ Branch 0 taken 1040528 times.
✓ Branch 1 taken 145 times.
1040673 if (origin_scr->ffcs[i].flags&ffc_carryover)
6374 {
6375 145 origin_ffc_overlay = true;
6376 145 break;
6377 }
6378 1040528 }
6379 36358 }
6380
6381
3/4
✓ Branch 0 taken 36360 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 145 times.
✓ Branch 3 taken 36215 times.
36360 if (origin_screen_overlay || origin_ffc_overlay)
6382 {
6383
2/2
✓ Branch 0 taken 1015 times.
✓ Branch 1 taken 145 times.
1160 for (int i = 0; i <= 6; i++)
6384 {
6385 1015 mapscr* prev_scr = get_scr_layer(cur_screen, i);
6386
1/2
✓ Branch 0 taken 1015 times.
✗ Branch 1 not taken.
1015 if (prev_scr)
6387 1015 prev_origin_scrs[i] = *prev_scr;
6388 else
6389 prev_origin_scrs[i] = {};
6390 1015 }
6391 145 }
6392 36360 }
6393
6394 // When loading a new screen, all previous FFC scripts end, with one exception.
6395 // Based on origin_ffc_overlay, some ffc scripts don't get reset. This set starts with all of
6396 // them, but scripts that need their data to persist will be removed.
6397 37530 loadscr_ffc_script_ids_to_remove.clear();
6398
2/2
✓ Branch 0 taken 83199388 times.
✓ Branch 1 taken 37530 times.
83236918 for (auto& key : scriptEngineDatas | std::views::keys)
6399 {
6400
2/2
✓ Branch 0 taken 82068435 times.
✓ Branch 1 taken 1130953 times.
83199388 if (key.first == ScriptType::FFC)
6401 1130953 loadscr_ffc_script_ids_to_remove.insert(key.second);
6402 }
6403
6404 37530 load_region(destdmap, screen);
6405
2/2
✓ Branch 0 taken 907 times.
✓ Branch 1 taken 36623 times.
37530 home_screen = screen >= 0x80 ? Hero.current_screen : cur_screen;
6406 37530 Hero.current_screen = screen;
6407
6408 37530 cpos_clear_all();
6409 37530 FFCore.destroyScriptableObjectsOfType(ScriptType::Screen);
6410 37530 FFCore.clear_combo_scripts();
6411
6412
2/2
✓ Branch 0 taken 164 times.
✓ Branch 1 taken 37366 times.
37530 if (is_in_scrolling_region())
6413 {
6414
2/2
✓ Branch 0 taken 20992 times.
✓ Branch 1 taken 164 times.
21156 for (int screen = 0; screen < 128; screen++)
6415 {
6416
2/2
✓ Branch 0 taken 19584 times.
✓ Branch 1 taken 1408 times.
20992 if (is_in_current_region(screen))
6417 {
6418
1/2
✓ Branch 0 taken 1408 times.
✗ Branch 1 not taken.
1408 bool screen_overlay = origin_screen_overlay && screen == cur_screen;
6419
1/2
✓ Branch 0 taken 1408 times.
✗ Branch 1 not taken.
1408 bool ffc_overlay = origin_ffc_overlay && screen == cur_screen;
6420 1408 load_a_screen_and_layers_init(destdmap, screen, ldir, screen_overlay, ffc_overlay);
6421 1408 }
6422 20992 }
6423 164 }
6424 else
6425 {
6426 37366 load_a_screen_and_layers_init(destdmap, screen, ldir, origin_screen_overlay, origin_ffc_overlay);
6427 }
6428
6429 37530 prepare_current_region_handles();
6430
6431
2/2
✓ Branch 0 taken 164 times.
✓ Branch 1 taken 37366 times.
37530 if (is_in_scrolling_region())
6432 {
6433
2/2
✓ Branch 0 taken 20992 times.
✓ Branch 1 taken 164 times.
21156 for (int screen = 0; screen < 128; screen++)
6434 {
6435
2/2
✓ Branch 0 taken 19584 times.
✓ Branch 1 taken 1408 times.
20992 if (is_in_current_region(screen))
6436 {
6437 1408 load_a_screen_and_layers_post(destdmap, screen, ldir);
6438 1408 }
6439 20992 }
6440 164 }
6441 else
6442 {
6443 37366 load_a_screen_and_layers_post(destdmap, screen, ldir);
6444 }
6445
6446 // If on a special screen, load the screen the player is currently on (home_screen) into special_warp_return_scr.
6447
2/2
✓ Branch 0 taken 36623 times.
✓ Branch 1 taken 907 times.
37530 if (screen >= 0x80)
6448
2/2
✓ Branch 0 taken 476 times.
✓ Branch 1 taken 431 times.
907 loadscr_old(orig_destdmap, home_screen, no_x80_dir ? -1 : ldir, origin_screen_overlay);
6449
6450 37530 update_slope_comboposes();
6451 37530 cpos_force_update();
6452 37530 trig_trigger_groups();
6453
6454
2/2
✓ Branch 0 taken 1130678 times.
✓ Branch 1 taken 37530 times.
1168208 for (int index : loadscr_ffc_script_ids_to_remove)
6455 {
6456 // Note: ideally would use "destroySprite", but during scrolling the previous
6457 // screen's FFCs are still accessible (even though only the new screen's FFC scripts run).
6458 // The only difference is a call to "release_sprite_owned_objects". To defer FFC script
6459 // owned objects being released until the end of the scroll, here "destroyScriptableObject"
6460 // is used instead.
6461 //
6462 // So when is "release_sprite_owned_objects" called for FFCs? For scrolling screen
6463 // transitions, it's at the end of "scrollscr" via "delete_temporary_screens". Otherwise,
6464 // it is called above when "load_region" calls "clear_temporary_screens".
6465 1130678 FFCore.destroyScriptableObject(ScriptType::FFC, index);
6466 }
6467
6468 // "extended height mode" includes the top 56 pixels as part of the visible mapscr viewport,
6469 // allowing for regions to display 4 more rows of combos (as many as ALTTP does). This part of
6470 // screen is normally reserved for the passive subscreen, but in this mode mapscr combos are drawn below it.
6471 // It is up to the quest designer to make their subscreen be actually transparent.
6472 //
6473 // When not in "extended height mode" (otherwise 56 is 0):
6474 // - playing_field_offset: 56, but changes during earthquakes
6475 // - original_playing_field_offset: always 56
6476 //
6477 // These values are used to adjust where things are drawn on screen to account for the passive subscreen. Examples:
6478 // - yofs of sprites
6479 // - bitmap y offsets in draw_screen
6480 // - drawing offsets for putscr, do_layer
6481 // - drawing offsets for various calls to overtile16 (see bomb weapon explosion)
6482 // - lots more
6483 //
6484 // TODO: consider refactor of yofs, make yofs start as 0 by default and add playing_field_offset at draw time?
6485
2/2
✓ Branch 0 taken 142 times.
✓ Branch 1 taken 37388 times.
37530 if (is_extended_height_mode())
6486 {
6487 142 playing_field_offset = 0;
6488 142 original_playing_field_offset = 0;
6489 // A few sprites exist as globals, so we must manually reset them.
6490 142 Hero.yofs = 0;
6491 142 mblock2.yofs = 0;
6492 142 }
6493 else
6494 {
6495 37388 mblock2.yofs = Hero.yofs = playing_field_offset = 56;
6496 37388 original_playing_field_offset = 56;
6497 }
6498 37530 is_any_room_dark = is_any_dark();
6499
6500 37530 game->load_portal();
6501 37530 throwGenScriptEvent(GENSCR_EVENT_CHANGE_SCREEN);
6502
3/4
✓ Branch 0 taken 35 times.
✓ Branch 1 taken 37495 times.
✓ Branch 2 taken 35 times.
✗ Branch 3 not taken.
37530 if (Hero.lift_wpn && get_qr(qr_CARRYABLE_NO_ACROSS_SCREEN))
6503 {
6504 delete Hero.lift_wpn;
6505 Hero.lift_wpn = nullptr;
6506 }
6507
6508 37530 enemy_spawning_has_checked_been_here = false;
6509 37530 markBmap(-1, Hero.current_screen);
6510 37530 Hero.maybe_begin_advanced_maze();
6511 37530 }
6512
6513 // Don't use this directly! Use `loadscr` instead.
6514 907 void loadscr_old(int32_t destdmap, int32_t screen,int32_t ldir,bool overlay)
6515 {
6516
1/2
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
907 int32_t destlvl = DMaps[destdmap < 0 ? cur_dmap : destdmap].level;
6517
6518 907 mapscr previous_scr = *special_warp_return_scr;
6519 907 mapscr* scr = special_warp_return_scr;
6520
1/2
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
907 const mapscr* source = get_canonical_scr(cur_map, screen);
6521
1/2
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
907 *scr = *source;
6522
6523
2/2
✓ Branch 0 taken 5442 times.
✓ Branch 1 taken 907 times.
6349 for (int i = 1; i <= 6; i++)
6524 {
6525
2/2
✓ Branch 0 taken 5059 times.
✓ Branch 1 taken 383 times.
5442 if (scr->layermap[i-1] > 0)
6526
2/4
✓ Branch 0 taken 383 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 383 times.
✗ Branch 3 not taken.
383 special_warp_return_scrs[i] = *get_canonical_scr(scr->layermap[i-1] - 1, scr->layerscreen[i-1]);
6527 else
6528
2/4
✓ Branch 0 taken 5059 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 5059 times.
✗ Branch 3 not taken.
5059 special_warp_return_scrs[i] = {};
6529 5442 }
6530
6531 907 scr->valid |= mVALID; //layer 0 is always valid
6532
6533
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 907 times.
907 if ( source->script > 0 )
6534 {
6535 scr->script = source->script;
6536 for ( int32_t q = 0; q < 8; q++ )
6537 {
6538 scr->screeninitd[q] = source->screeninitd[q];
6539 }
6540 FFCore.reset_script_engine_data(ScriptType::Screen, screen);
6541 }
6542 else
6543 {
6544 907 scr->script = 0;
6545 }
6546
6547
1/2
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
907 if(overlay)
6548 {
6549 for(int32_t c=0; c< 176; ++c)
6550 {
6551 if(scr->data[c]==0)
6552 {
6553 scr->data[c]=previous_scr.data[c];
6554 scr->sflag[c]=previous_scr.sflag[c];
6555 scr->cset[c]=previous_scr.cset[c];
6556 }
6557 }
6558
6559 for(int32_t i=0; i<6; i++)
6560 {
6561 if(previous_scr.layermap[i]>0 && scr->layermap[i]>0)
6562 {
6563 int32_t lm = (scr->layermap[i]-1)*MAPSCRS+scr->layerscreen[i];
6564 int32_t fm = (previous_scr.layermap[i]-1)*MAPSCRS+previous_scr.layerscreen[i];
6565
6566 for(int32_t c=0; c< 176; ++c)
6567 {
6568 if(TheMaps[lm].data[c]==0)
6569 {
6570 TheMaps[lm].data[c] = TheMaps[fm].data[c];
6571 TheMaps[lm].sflag[c] = TheMaps[fm].sflag[c];
6572 TheMaps[lm].cset[c] = TheMaps[fm].cset[c];
6573 }
6574 }
6575 }
6576 }
6577 }
6578
6579
1/2
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
29900 auto [offx, offy] = translate_screen_coordinates_to_world(screen);
6580
1/2
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
907 int c = scr->numFFC();
6581
2/2
✓ Branch 0 taken 907 times.
✓ Branch 1 taken 28993 times.
29900 for (word i = 0; i < c; i++)
6582 {
6583 28993 scr->ffcs[i].screen_spawned = screen;
6584
1/2
✓ Branch 0 taken 28993 times.
✗ Branch 1 not taken.
28993 scr->ffcs[i].x += offx;
6585
1/2
✓ Branch 0 taken 28993 times.
✗ Branch 1 not taken.
28993 scr->ffcs[i].y += offy;
6586 28993 }
6587
6588 907 int mi = mapind(cur_map, screen);
6589
6590 // Apply perm secrets, if applicable.
6591
3/4
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 536 times.
✓ Branch 3 taken 371 times.
907 if(canPermSecret(destdmap,screen))
6592 {
6593
3/4
✓ Branch 0 taken 536 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 204 times.
✓ Branch 3 taken 332 times.
536 if(game->maps[mi]&mSECRET) // if special stuff done before
6594 {
6595
1/2
✓ Branch 0 taken 204 times.
✗ Branch 1 not taken.
204 reveal_hidden_stairs(scr, screen, false);
6596
6597
1/2
✓ Branch 0 taken 204 times.
✗ Branch 1 not taken.
204 log_trigger_secret_reason(TriggerSource::SecretsScreenState);
6598
1/2
✓ Branch 0 taken 204 times.
✗ Branch 1 not taken.
204 get_screen_state(special_warp_return_scr->screen).triggered_secrets = true;
6599 204 bool do_replay_comment = true;
6600 204 bool from_active_screen = false;
6601
2/4
✓ Branch 0 taken 204 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 204 times.
✗ Branch 3 not taken.
204 trigger_secrets_for_screen_internal(create_screen_handles(special_warp_return_scr), from_active_screen, false, -1, do_replay_comment);
6602 204 }
6603
2/4
✓ Branch 0 taken 536 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 536 times.
✗ Branch 3 not taken.
536 if(game->maps[mi]&mLIGHTBEAM) // if special stuff done before
6604 {
6605 for (int layer = 0; layer <= 6; layer++)
6606 {
6607 mapscr* tscr = &special_warp_return_scrs[layer];
6608 for (int pos = 0; pos < 176; pos++)
6609 {
6610 newcombo const* cmb = &combobuf[tscr->data[pos]];
6611 if(cmb->type == cLIGHTTARGET)
6612 {
6613 if(!(cmb->usrflags&cflag1)) //Unlit version
6614 {
6615 tscr->data[pos] += 1;
6616 }
6617 }
6618 }
6619 }
6620 }
6621 536 }
6622
6623 screen_handles_t screen_handles;
6624
2/2
✓ Branch 0 taken 907 times.
✓ Branch 1 taken 6349 times.
7256 for (int i = 0; i <= 6; i++)
6625
3/4
✓ Branch 0 taken 6349 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1284 times.
✓ Branch 3 taken 5065 times.
6349 screen_handles[i] = {scr, special_warp_return_scrs[i].is_valid() ? &special_warp_return_scrs[i] : nullptr, screen, i};
6626
6627
2/4
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 907 times.
✗ Branch 3 not taken.
907 toggle_switches(game->lvlswitches[destlvl], true, screen_handles);
6628
1/2
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
907 toggle_gswitches_load(screen_handles);
6629
6630
3/4
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 5 times.
✓ Branch 3 taken 902 times.
907 if(game->maps[mi]&mLOCKBLOCK) // if special stuff done before
6631 {
6632
1/2
✓ Branch 0 taken 5 times.
✗ Branch 1 not taken.
5 remove_lockblocks(screen_handles);
6633 5 }
6634
6635
3/4
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 906 times.
907 if(game->maps[mi]&mBOSSLOCKBLOCK) // if special stuff done before
6636 {
6637
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 remove_bosslockblocks(screen_handles);
6638 1 }
6639
6640
2/4
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 907 times.
907 if(game->maps[mi]&mCHEST) // if special stuff done before
6641 {
6642 remove_chests(screen_handles);
6643 }
6644
6645
2/4
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 907 times.
907 if(game->maps[mi]&mLOCKEDCHEST) // if special stuff done before
6646 {
6647 remove_lockedchests(screen_handles);
6648 }
6649
6650
2/4
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 907 times.
907 if(game->maps[mi]&mBOSSCHEST) // if special stuff done before
6651 {
6652 remove_bosschests(screen_handles);
6653 }
6654
6655
1/2
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
907 clear_xdoors(screen_handles, true);
6656
1/2
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
907 clear_xstatecombos(screen_handles, true);
6657
6658 // check doors
6659
3/4
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 536 times.
✓ Branch 3 taken 371 times.
907 if (isdungeon(destdmap, screen))
6660 {
6661
2/2
✓ Branch 0 taken 1484 times.
✓ Branch 1 taken 371 times.
1855 for(int32_t i=0; i<4; i++)
6662 {
6663 1484 int32_t door=scr->door[i];
6664
6665
4/5
✓ Branch 0 taken 91 times.
✓ Branch 1 taken 9 times.
✓ Branch 2 taken 89 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1295 times.
1484 switch(door)
6666 {
6667 case d1WAYSHUTTER:
6668 case dSHUTTER:
6669 if ((ldir^1)==i && screen == home_screen)
6670 {
6671 scr->door[i]=dOPENSHUTTER;
6672 }
6673
6674 get_screen_state(screen).open_doors = -4;
6675 105 break;
6676
6677 case dLOCKED:
6678
3/4
✓ Branch 0 taken 91 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 11 times.
✓ Branch 3 taken 80 times.
91 if(game->maps[mi]&(mDOOR_UP<<i))
6679 {
6680 80 scr->door[i]=dUNLOCKED;
6681 80 }
6682
6683 91 break;
6684
6685 case dBOSS:
6686
3/4
✓ Branch 0 taken 9 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
✓ Branch 3 taken 5 times.
9 if(game->maps[mi]&(mDOOR_UP<<i))
6687 {
6688 5 scr->door[i]=dOPENBOSS;
6689 5 }
6690
6691 9 break;
6692
6693 case dBOMB:
6694
3/4
✓ Branch 0 taken 89 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 38 times.
✓ Branch 3 taken 51 times.
89 if(game->maps[mi]&(mDOOR_UP<<i))
6695 {
6696 51 scr->door[i]=dBOMBED;
6697 51 }
6698
6699 89 break;
6700 }
6701
6702
2/2
✓ Branch 0 taken 1484 times.
✓ Branch 1 taken 105 times.
1589 update_door(scr, i, scr->door[i]);
6703
6704
4/4
✓ Branch 0 taken 1390 times.
✓ Branch 1 taken 94 times.
✓ Branch 2 taken 11 times.
✓ Branch 3 taken 1379 times.
1484 if(door==dSHUTTER||door==d1WAYSHUTTER)
6705 {
6706 105 scr->door[i]=door;
6707 105 }
6708 1484 }
6709 371 }
6710
6711
2/2
✓ Branch 0 taken 6139 times.
✓ Branch 1 taken 1117 times.
7256 for(int32_t j=-1; j<6; ++j) // j == -1 denotes the current screen
6712 {
6713
4/4
✓ Branch 0 taken 5442 times.
✓ Branch 1 taken 697 times.
✓ Branch 2 taken 593 times.
✓ Branch 3 taken 4849 times.
6139 if (j<0 || scr->layermap[j] > 0)
6714 {
6715
4/4
✓ Branch 0 taken 383 times.
✓ Branch 1 taken 907 times.
✓ Branch 2 taken 382 times.
✓ Branch 3 taken 1 times.
1290 mapscr *layerscreen= (j<0 ? scr : special_warp_return_scrs[j+1].valid ? &special_warp_return_scrs[j+1] :
6716 1 &TheMaps[(scr->layermap[j]-1)*MAPSCRS]+scr->layerscreen[j]);
6717
6718
2/2
✓ Branch 0 taken 226830 times.
✓ Branch 1 taken 1500 times.
228330 for(int32_t i=0; i<176; ++i)
6719 {
6720 226830 int32_t c=layerscreen->data[i];
6721
6722 // New screen flag: Cycle Combos At Screen Init
6723
5/8
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 226824 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 6 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✓ Branch 6 taken 210 times.
✓ Branch 7 taken 210 times.
226830 if(combobuf[c].nextcombo != 0 && (scr->flags3 & fCYCLEONINIT) && (j<0 || get_qr(qr_CMBCYCLELAYERS)))
6724 {
6725 210 int32_t r = 0;
6726
6727
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 210 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
210 while(combobuf[c].can_cycle() && r++ < 10)
6728 {
6729 newcombo const& cmb = combobuf[c];
6730 bool cycle_under = (cmb.animflags & AF_CYCLEUNDERCOMBO);
6731 auto cid = cycle_under ? layerscreen->undercombo : cmb.nextcombo;
6732 layerscreen->data[i] = cid;
6733 if(!(combobuf[c].animflags & AF_CYCLENOCSET))
6734 layerscreen->cset[i] = cycle_under ? layerscreen->undercset : cmb.nextcset;
6735 c = layerscreen->data[i];
6736 }
6737 }
6738 227040 }
6739 1500 }
6740 6349 }
6741 1537 }
6742
6743 // Load screen (and layers). Unlike loadscr, this doesn't load to the global temporary_screens, but
6744 // instead returns an array of mapscr.
6745 // Used to draw/save the map.
6746 47360 std::array<mapscr, 7> loadscr2(int32_t screen)
6747 {
6748 47360 std::array<mapscr, 7> scrs;
6749 47360 mapscr* scr = &scrs[0];
6750
6751
2/2
✓ Branch 0 taken 66834661 times.
✓ Branch 1 taken 47360 times.
66882021 for(word x=0; x<animated_combos; x++)
6752 {
6753
2/2
✓ Branch 0 taken 33899045 times.
✓ Branch 1 taken 32935616 times.
66834661 if(combobuf[animated_combo_table4[x][0]].nextcombo!=0)
6754 {
6755 32935616 combobuf[animated_combo_table4[x][0]].aclk=0;
6756 32935616 }
6757 66834661 }
6758
6759
1/2
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
47360 const mapscr* source = get_canonical_scr(cur_map, screen);
6760
2/4
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 47360 times.
✗ Branch 3 not taken.
47360 if (!source->is_valid())
6761 {
6762 scrs[0].valid = 0;
6763 return scrs;
6764 }
6765
6766
2/4
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 47360 times.
✗ Branch 3 not taken.
47360 *scr = *get_canonical_scr(cur_map, screen);
6767
2/2
✓ Branch 0 taken 284160 times.
✓ Branch 1 taken 47360 times.
331520 for (int i = 1; i <= 6; i++)
6768 {
6769
2/2
✓ Branch 0 taken 209501 times.
✓ Branch 1 taken 74659 times.
284160 if (scr->layermap[i-1] > 0)
6770
2/4
✓ Branch 0 taken 74659 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 74659 times.
✗ Branch 3 not taken.
74659 scrs[i] = *get_canonical_scr(scr->layermap[i-1] - 1, scr->layerscreen[i-1]);
6771 else
6772
2/4
✓ Branch 0 taken 209501 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 209501 times.
✗ Branch 3 not taken.
209501 scrs[i] = {};
6773 284160 }
6774
6775 screen_handles_t screen_handles;
6776
2/2
✓ Branch 0 taken 47360 times.
✓ Branch 1 taken 331520 times.
378880 for (int i = 0; i < 7; i++)
6777
3/4
✓ Branch 0 taken 331520 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 114582 times.
✓ Branch 3 taken 216938 times.
331520 screen_handles[i] = {scr, scrs[i].is_valid() ? &scrs[i] : nullptr, screen, i};
6778
6779 47360 int mi = mapind(cur_map, screen);
6780
6781
3/4
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 47306 times.
✓ Branch 3 taken 54 times.
47360 if(canPermSecret(-1,screen))
6782 {
6783
3/4
✓ Branch 0 taken 47306 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 6344 times.
✓ Branch 3 taken 40962 times.
47306 if(game->maps[mi]&mSECRET) // if special stuff done before
6784 {
6785
1/2
✓ Branch 0 taken 6344 times.
✗ Branch 1 not taken.
6344 reveal_hidden_stairs(scr, screen, false);
6786 6344 bool from_active_screen = false;
6787 6344 bool do_replay_comment = true;
6788
1/2
✓ Branch 0 taken 6344 times.
✗ Branch 1 not taken.
6344 trigger_secrets_for_screen_internal(screen_handles, from_active_screen, false, -1, do_replay_comment);
6789 6344 }
6790
3/4
✓ Branch 0 taken 47306 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 47289 times.
✓ Branch 3 taken 17 times.
47306 if(game->maps[mi]&mLIGHTBEAM) // if special stuff done before
6791 {
6792
2/2
✓ Branch 0 taken 119 times.
✓ Branch 1 taken 17 times.
136 for (int layer = 0; layer <= 6; layer++)
6793 {
6794 119 mapscr* tscr = &scrs[layer];
6795
2/2
✓ Branch 0 taken 20944 times.
✓ Branch 1 taken 119 times.
21063 for (int pos = 0; pos < 176; pos++)
6796 {
6797 20944 newcombo const* cmb = &combobuf[tscr->data[pos]];
6798
2/2
✓ Branch 0 taken 20927 times.
✓ Branch 1 taken 17 times.
20944 if(cmb->type == cLIGHTTARGET)
6799 {
6800
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 17 times.
17 if(!(cmb->usrflags&cflag1)) //Unlit version
6801 {
6802 17 tscr->data[pos] += 1;
6803 17 }
6804 17 }
6805 20944 }
6806 119 }
6807 17 }
6808 47306 }
6809
6810
3/4
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 271 times.
✓ Branch 3 taken 47089 times.
47360 if(game->maps[mi]&mLOCKBLOCK) // if special stuff done before
6811 {
6812
1/2
✓ Branch 0 taken 271 times.
✗ Branch 1 not taken.
271 remove_lockblocks(screen_handles);
6813 271 }
6814
6815
3/4
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 47359 times.
47360 if(game->maps[mi]&mBOSSLOCKBLOCK) // if special stuff done before
6816 {
6817
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 remove_bosslockblocks(screen_handles);
6818 1 }
6819
6820
3/4
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 106 times.
✓ Branch 3 taken 47254 times.
47360 if(game->maps[mi]&mCHEST) // if special stuff done before
6821 {
6822
1/2
✓ Branch 0 taken 106 times.
✗ Branch 1 not taken.
106 remove_chests(screen_handles);
6823 106 }
6824
6825
3/4
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 24 times.
✓ Branch 3 taken 47336 times.
47360 if(game->maps[mi]&mLOCKEDCHEST) // if special stuff done before
6826 {
6827
1/2
✓ Branch 0 taken 24 times.
✗ Branch 1 not taken.
24 remove_lockedchests(screen_handles);
6828 24 }
6829
6830
2/4
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 47360 times.
47360 if(game->maps[mi]&mBOSSCHEST) // if special stuff done before
6831 {
6832 remove_bosschests(screen_handles);
6833 }
6834
6835
1/2
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
47360 clear_xdoors(screen_handles);
6836
1/2
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
47360 clear_xstatecombos(screen_handles);
6837
6838 // check doors
6839
3/4
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 47306 times.
✓ Branch 3 taken 54 times.
47360 if (isdungeon(screen))
6840 {
6841
2/2
✓ Branch 0 taken 216 times.
✓ Branch 1 taken 54 times.
270 for(int32_t i=0; i<4; i++)
6842 {
6843 216 int32_t door=scr->door[i];
6844 216 bool putit=true;
6845
6846
4/5
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 61 times.
✓ Branch 4 taken 139 times.
216 switch(door)
6847 {
6848 case d1WAYSHUTTER:
6849 case dSHUTTER:
6850 61 break;
6851
6852 case dLOCKED:
6853
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 12 times.
12 if(game->maps[mi]&(mDOOR_UP<<i))
6854 {
6855 12 scr->door[i]=dUNLOCKED;
6856 12 }
6857
6858 12 break;
6859
6860 case dBOSS:
6861
2/4
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
4 if(game->maps[mi]&(mDOOR_UP<<i))
6862 {
6863 scr->door[i]=dOPENBOSS;
6864 }
6865
6866 4 break;
6867
6868 case dBOMB:
6869 if(game->maps[mi]&(mDOOR_UP<<i))
6870 {
6871 scr->door[i]=dBOMBED;
6872 }
6873
6874 break;
6875 }
6876
6877
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 216 times.
216 if(putit)
6878 {
6879
1/2
✓ Branch 0 taken 216 times.
✗ Branch 1 not taken.
216 putdoor(scr, scrollbuf, i, scr->door[i], false);
6880 216 }
6881
6882
3/4
✓ Branch 0 taken 155 times.
✓ Branch 1 taken 61 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 155 times.
216 if(door==dSHUTTER||door==d1WAYSHUTTER)
6883 {
6884 61 scr->door[i]=door;
6885 61 }
6886 216 }
6887 54 }
6888
6889
2/2
✓ Branch 0 taken 331520 times.
✓ Branch 1 taken 47360 times.
378880 for(int32_t j=-1; j<6; ++j) // j == -1 denotes the current screen
6890 {
6891
4/4
✓ Branch 0 taken 284160 times.
✓ Branch 1 taken 47360 times.
✓ Branch 2 taken 74659 times.
✓ Branch 3 taken 209501 times.
331520 if (j < 0 || scr->layermap[j] > 0)
6892 {
6893
2/2
✓ Branch 0 taken 74659 times.
✓ Branch 1 taken 47360 times.
122019 mapscr *layerscreen= (j<0 ? scr
6894 74659 : &(TheMaps[(scr->layermap[j]-1)*MAPSCRS+scr->layerscreen[j]]));
6895
6896
2/2
✓ Branch 0 taken 21475344 times.
✓ Branch 1 taken 122019 times.
21597363 for(int32_t i=0; i<176; ++i)
6897 {
6898 21475344 int32_t c=layerscreen->data[i];
6899
6900 // New screen flag: Cycle Combos At Screen Init
6901
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 21475344 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
21475344 if((scr->flags3 & fCYCLEONINIT) && (j<0 || get_qr(qr_CMBCYCLELAYERS)))
6902 {
6903 int32_t r = 0;
6904
6905 while(combobuf[c].can_cycle() && r++ < 10)
6906 {
6907 newcombo const& cmb = combobuf[c];
6908 bool cycle_under = (cmb.animflags & AF_CYCLEUNDERCOMBO);
6909 auto cid = cycle_under ? layerscreen->undercombo : cmb.nextcombo;
6910 layerscreen->data[i] = cid;
6911 if(!(combobuf[c].animflags & AF_CYCLENOCSET))
6912 layerscreen->cset[i] = cycle_under ? layerscreen->undercset : cmb.nextcset;
6913 c = layerscreen->data[i];
6914 }
6915 }
6916 21475344 }
6917 122019 }
6918 331520 }
6919
6920 47360 return scrs;
6921
1/2
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
47360 }
6922
6923 19763683 void putscr(mapscr* scr, BITMAP* dest, int32_t x, int32_t y)
6924 {
6925 // This is a bogus value while screenscrolling == true, but that's ok
6926 // because it is only used to calculate the rpos, and during screenscrolling
6927 // only the modulus to get pos (draw_cmb_pos does RPOS_TO_POS) is needed, which
6928 // is always the same no matter the value of scr.
6929 19763683 int screen = get_screen_for_world_xy(x, y);
6930
6931 19763683 x -= viewport.x;
6932 19763683 y -= viewport.y;
6933
6934
3/6
✓ Branch 0 taken 19763683 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 19763683 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 19763683 times.
19763683 if (!scr->is_valid()||!show_layers[0]||scr->hidelayers & 1)
6935 {
6936 rectfill(dest,x,y,x+255,y+175,0);
6937 return;
6938 }
6939
6940 39379899 bool over = XOR(scr->flags7&fLAYER2BG,DMaps[cur_dmap].flags&dmfLAYER2BG)
6941
2/2
✓ Branch 0 taken 19616216 times.
✓ Branch 1 taken 147467 times.
19763683 || XOR(scr->flags7&fLAYER3BG, DMaps[cur_dmap].flags&dmfLAYER3BG)
6942
2/2
✓ Branch 0 taken 243651 times.
✓ Branch 1 taken 19372565 times.
19616216 || !get_qr(qr_CLASSIC_DRAWING_ORDER);
6943
6944 int start_x, end_x, start_y, end_y;
6945 19763683 get_bounds_for_draw_cmb_calls(dest, x, y, start_x, end_x, start_y, end_y);
6946
2/2
✓ Branch 0 taken 19763683 times.
✓ Branch 1 taken 210499187 times.
230262870 for (int cy = start_y; cy < end_y; cy++)
6947 {
6948
2/2
✓ Branch 0 taken 3195985218 times.
✓ Branch 1 taken 210499187 times.
3406484405 for (int cx = start_x; cx < end_x; cx++)
6949 {
6950 3195985218 int i = cx + cy*16;
6951
2/2
✓ Branch 0 taken 374288294 times.
✓ Branch 1 taken 2821696924 times.
3195985218 auto rpos = screenscrolling ? rpos_t::None : POS_TO_RPOS(i, screen);
6952 3195985218 draw_cmb_pos(dest, x + cx*16, y + cy*16, rpos, scr->data[i], scr->cset[i], 0, over, false);
6953 3195985218 }
6954 210499187 }
6955 19763683 }
6956
6957 16129780 static void putscrdoors(const nearby_screens_t& nearby_screens, BITMAP *dest, int32_t x, int32_t y)
6958 {
6959
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16129780 times.
16129780 if (!show_layers[0])
6960 {
6961 return;
6962 }
6963
6964 16129780 x -= viewport.x;
6965 16129780 y -= viewport.y;
6966
6967
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16129780 times.
32395878 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
6968 16266098 mapscr* scr = screen_handles[0].base_scr;
6969
1/2
✓ Branch 0 taken 16266098 times.
✗ Branch 1 not taken.
16266098 if (!scr->is_valid())
6970 return;
6971
6972
2/2
✓ Branch 0 taken 123411 times.
✓ Branch 1 taken 16142687 times.
16266098 if(scr->door[0]==dBOMBED)
6973 {
6974 123411 over_door(scr, dest, 39, up, offx+x, offy+y);
6975 123411 }
6976
6977
2/2
✓ Branch 0 taken 143109 times.
✓ Branch 1 taken 16122989 times.
16266098 if(scr->door[1]==dBOMBED)
6978 {
6979 143109 over_door(scr, dest, 135, down, offx+x, offy+y);
6980 143109 }
6981
6982
2/2
✓ Branch 0 taken 155862 times.
✓ Branch 1 taken 16110236 times.
16266098 if(scr->door[2]==dBOMBED)
6983 {
6984 155862 over_door(scr, dest, 66, left, offx+x, offy+y);
6985 155862 }
6986
6987
2/2
✓ Branch 0 taken 132289 times.
✓ Branch 1 taken 16133809 times.
16266098 if(scr->door[3]==dBOMBED)
6988 {
6989 132289 over_door(scr, dest, 77, right, offx+x, offy+y);
6990 132289 }
6991 16266098 });
6992 16129780 }
6993
6994 3497585 void putscrdoors(mapscr* scr, BITMAP *dest, int32_t x, int32_t y)
6995 {
6996
2/4
✓ Branch 0 taken 3497585 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3497585 times.
✗ Branch 3 not taken.
3497585 if (!scr->is_valid() || !show_layers[0])
6997 return;
6998
6999 3497585 x -= viewport.x;
7000 3497585 y -= viewport.y;
7001
7002
2/2
✓ Branch 0 taken 37656 times.
✓ Branch 1 taken 3459929 times.
3497585 if(scr->door[0]==dBOMBED)
7003 {
7004 37656 over_door(scr,dest,39,up,x,y);
7005 37656 }
7006
7007
2/2
✓ Branch 0 taken 36495 times.
✓ Branch 1 taken 3461090 times.
3497585 if(scr->door[1]==dBOMBED)
7008 {
7009 36495 over_door(scr,dest,135,down,x,y);
7010 36495 }
7011
7012
2/2
✓ Branch 0 taken 40440 times.
✓ Branch 1 taken 3457145 times.
3497585 if(scr->door[2]==dBOMBED)
7013 {
7014 40440 over_door(scr,dest,66,left,x,y);
7015 40440 }
7016
7017
2/2
✓ Branch 0 taken 37063 times.
✓ Branch 1 taken 3460522 times.
3497585 if(scr->door[3]==dBOMBED)
7018 {
7019 37063 over_door(scr,dest,77,right,x,y);
7020 37063 }
7021 3497585 }
7022 262955462 static inline bool standing_on_z(newcombo const& cmb, zfix const& standing_z_state)
7023 {
7024
1/2
✓ Branch 0 taken 262955462 times.
✗ Branch 1 not taken.
262955462 if (cmb.dive_under_level)
7025 {
7026 if (standing_z_state <= -cmb.dive_under_level)
7027 return true;
7028 }
7029
7030 262955462 zfix cmb_z, cmb_z_step;
7031
4/4
✓ Branch 0 taken 92789 times.
✓ Branch 1 taken 262862673 times.
✓ Branch 2 taken 88819 times.
✓ Branch 3 taken 3970 times.
262955462 if(cmb.type == cCSWITCHBLOCK && (cmb.usrflags & cflag9))
7032 {
7033 3970 cmb_z = zslongToFix(cmb.attributes[2]);
7034
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3970 times.
3970 cmb_z_step = zslongToFix(zc_max(0,cmb.attributes[3]));
7035 3970 }
7036
2/2
✓ Branch 0 taken 1983 times.
✓ Branch 1 taken 262949509 times.
262951492 else if(cmb.genflags & cflag3)
7037 {
7038 1983 cmb_z = cmb.z_height;
7039
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1983 times.
1983 cmb_z_step = zc_max(0_zf,cmb.z_step_height);
7040 1983 }
7041 262949509 else return false;
7042
7043
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5953 times.
5953 if (standing_z_state == STANDING_Z_MAX) // 'infinity'
7044 return true;
7045
2/2
✓ Branch 0 taken 1149 times.
✓ Branch 1 taken 4804 times.
5953 if (!cmb_z) return false; // infinite height
7046
7047 4804 return (cmb_z - cmb_z_step) <= standing_z_state;
7048 262955462 }
7049 62153171 bool _walkflag(zfix_round zx,zfix_round zy,int32_t cnt)
7050 {
7051 62153171 return _walkflag(zx,zy,cnt,0_zf);
7052 }
7053
7054 142615198 bool _walkflag_new(const mapscr* s0, const mapscr* s1, const mapscr* s2, zfix_round zx, zfix_round zy, zfix const& standing_z_state, bool is_temp_screens)
7055 {
7056 142615198 int x = zx.getRound(), y = zy.getRound();
7057 142615198 int pos = COMBOPOS(x % 256, y % 176);
7058 142615198 const newcombo& c = combobuf[s0->data[pos]];
7059 142615198 const newcombo& c1 = combobuf[s1->data[pos]];
7060 142615198 const newcombo& c2 = combobuf[s2->data[pos]];
7061
4/4
✓ Branch 0 taken 140523572 times.
✓ Branch 1 taken 2091626 times.
✓ Branch 2 taken 140514112 times.
✓ Branch 3 taken 9460 times.
285460386 bool dried = (((iswater_type(c.type)) || (iswater_type(c1.type)) ||
7062
4/4
✓ Branch 0 taken 114995 times.
✓ Branch 1 taken 140629107 times.
✓ Branch 2 taken 2211836 times.
✓ Branch 3 taken 4245 times.
142615198 (iswater_type(c2.type))) && DRIEDLAKE);
7063 142845188 int32_t b=1;
7064
2/2
✓ Branch 0 taken 70426244 times.
✓ Branch 1 taken 72418944 times.
142845188 if(x&8) b<<=2;
7065
2/2
✓ Branch 0 taken 66771726 times.
✓ Branch 1 taken 76073462 times.
142845188 if(y&8) b<<=1;
7066
7067 142845188 int32_t cwalkflag = c.walk;
7068
4/4
✓ Branch 0 taken 142730184 times.
✓ Branch 1 taken 115004 times.
✓ Branch 2 taken 142730020 times.
✓ Branch 3 taken 164 times.
142845188 if(is_temp_screens && standing_on_z(c,standing_z_state)) cwalkflag &= (c.walk>>4)^0xF;
7069
8/10
✓ Branch 0 taken 57502 times.
✓ Branch 1 taken 142787522 times.
✓ Branch 2 taken 2206612 times.
✓ Branch 3 taken 2149110 times.
✓ Branch 4 taken 2206612 times.
✓ Branch 5 taken 142730020 times.
✓ Branch 6 taken 2206612 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 2206612 times.
✗ Branch 9 not taken.
142845024 else if ((c.type == cBRIDGE && get_qr(qr_OLD_BRIDGE_COMBOS)) || (iswater_type(c.type) && ((c.walk>>4)&b) && ((c.usrflags&cflag3) || (c.usrflags&cflag4)))) cwalkflag = 0;
7070
2/2
✓ Branch 0 taken 63213807 times.
✓ Branch 1 taken 79516377 times.
142730184 if (s1 != s0)
7071 {
7072
3/4
✓ Branch 0 taken 79516377 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 79515759 times.
✓ Branch 3 taken 618 times.
79516377 if(is_temp_screens && standing_on_z(c1,standing_z_state)) cwalkflag &= (c1.walk>>4)^0xF;
7073
4/10
✓ Branch 0 taken 11729 times.
✓ Branch 1 taken 79504030 times.
✓ Branch 2 taken 11729 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 11729 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
79515759 else if ((iswater_type(c1.type) && ((c1.walk>>4)&b) && get_qr(qr_WATER_ON_LAYER_1) && !((c1.usrflags&cflag3) || (c1.usrflags&cflag4)))) cwalkflag &= c1.walk;
7074
2/2
✓ Branch 0 taken 71255 times.
✓ Branch 1 taken 79444504 times.
79515759 else if (c1.type == cBRIDGE)
7075 {
7076
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 71255 times.
71255 if (!get_qr(qr_OLD_BRIDGE_COMBOS))
7077 {
7078 71255 int efflag = (c1.walk & 0xF0)>>4;
7079 71255 int newsolid = (c1.walk & 0xF);
7080 71255 cwalkflag = ((newsolid | cwalkflag) & (~efflag)) | (newsolid & efflag);
7081 71255 }
7082 else cwalkflag &= c1.walk;
7083 71255 }
7084
3/8
✓ Branch 0 taken 11729 times.
✓ Branch 1 taken 79432775 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 11729 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
79444504 else if ((iswater_type(c1.type) && get_qr(qr_WATER_ON_LAYER_1) && ((c1.usrflags&cflag3) || (c1.usrflags&cflag4)) && ((c1.walk>>4)&b))) cwalkflag = 0;
7085 79444504 else cwalkflag |= c1.walk;
7086 79516377 }
7087
2/2
✓ Branch 0 taken 102021283 times.
✓ Branch 1 taken 40708901 times.
142730184 if (s2 != s0)
7088 {
7089
2/4
✓ Branch 0 taken 40708901 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 40708901 times.
✗ Branch 3 not taken.
40708901 if(is_temp_screens && standing_on_z(c2,standing_z_state)) cwalkflag &= (c2.walk>>4)^0xF;
7090
7/10
✓ Branch 0 taken 5889 times.
✓ Branch 1 taken 40703012 times.
✓ Branch 2 taken 5889 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 3735 times.
✓ Branch 5 taken 2154 times.
✓ Branch 6 taken 3735 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✓ Branch 9 taken 3735 times.
40708901 else if ((iswater_type(c2.type) && ((c2.walk>>4)&b) && get_qr(qr_WATER_ON_LAYER_2) && !((c2.usrflags&cflag3) || (c2.usrflags&cflag4)))) cwalkflag &= c2.walk;
7091
2/2
✓ Branch 0 taken 16725 times.
✓ Branch 1 taken 40688441 times.
40705166 else if (c2.type == cBRIDGE)
7092 {
7093
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16725 times.
16725 if (!get_qr(qr_OLD_BRIDGE_COMBOS))
7094 {
7095 16725 int efflag = (c2.walk & 0xF0)>>4;
7096 16725 int newsolid = (c2.walk & 0xF);
7097 16725 cwalkflag = ((newsolid | cwalkflag) & (~efflag)) | (newsolid & efflag);
7098 16725 }
7099 else cwalkflag &= c2.walk;
7100 16725 }
7101
3/8
✓ Branch 0 taken 2154 times.
✓ Branch 1 taken 40686287 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2154 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
40688441 else if ((iswater_type(c2.type) && get_qr(qr_WATER_ON_LAYER_2) && ((c2.usrflags&cflag3) || (c2.usrflags&cflag4))) && ((c2.walk>>4)&b)) cwalkflag = 0;
7102 40688441 else cwalkflag |= c2.walk;
7103 40708901 }
7104
7105
4/4
✓ Branch 0 taken 30808240 times.
✓ Branch 1 taken 111921944 times.
✓ Branch 2 taken 948 times.
✓ Branch 3 taken 30807292 times.
142730184 if((cwalkflag&b) && !dried)
7106 30807292 return true;
7107
7108
3/4
✓ Branch 0 taken 111922892 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 111853702 times.
✓ Branch 3 taken 69190 times.
111922892 if (is_temp_screens && collide_object(zx, zy, 0.0001_zf, 0.0001_zf)) return true;
7109
7110 111853702 return false;
7111 142730184 }
7112
7113 // Returns true if the combo at viewport position x,y is solid. Looks at a combo's quadrant walkablity flags.
7114 142730184 static bool _walkflag_new(zfix_round zx, zfix_round zy, zfix const& standing_z_state)
7115 {
7116 142730184 int x = zx.getRound(), y = zy.getRound();
7117 142730184 mapscr* s0 = get_scr_for_world_xy_layer(x, y, 0);
7118 142730184 mapscr* s1 = get_scr_for_world_xy_layer(x, y, 1);
7119 142730184 mapscr* s2 = get_scr_for_world_xy_layer(x, y, 2);
7120
2/2
✓ Branch 0 taken 63213807 times.
✓ Branch 1 taken 79516377 times.
142730184 if (!s1->valid) s1 = s0;
7121
2/2
✓ Branch 0 taken 102021283 times.
✓ Branch 1 taken 40708901 times.
142730184 if (!s2->valid) s2 = s0;
7122 142730184 return _walkflag_new(s0, s1, s2, zx, zy, standing_z_state, true);
7123 }
7124
7125 138202307 bool _walkflag(zfix_round x,zfix_round y,int32_t cnt,zfix const& standing_z_state)
7126 {
7127 138202307 int max_x = world_w;
7128 138202307 int max_y = world_h;
7129
2/2
✓ Branch 0 taken 78159570 times.
✓ Branch 1 taken 60042737 times.
138202307 if (!get_qr(qr_LTTPWALK))
7130 {
7131 60042737 max_x -= 7;
7132 60042737 max_y -= 7;
7133 60042737 }
7134
4/4
✓ Branch 0 taken 137929939 times.
✓ Branch 1 taken 272368 times.
✓ Branch 2 taken 83268 times.
✓ Branch 3 taken 137846671 times.
138202307 if (x < 0 || y < 0) return false;
7135
2/2
✓ Branch 0 taken 323548 times.
✓ Branch 1 taken 137523123 times.
137846671 if (x >= max_x) return false;
7136
3/4
✓ Branch 0 taken 571808 times.
✓ Branch 1 taken 136951315 times.
✓ Branch 2 taken 571808 times.
✗ Branch 3 not taken.
137523123 if (x >= max_x - 8 && cnt == 2) return false;
7137
2/2
✓ Branch 0 taken 136968860 times.
✓ Branch 1 taken 554263 times.
137523123 if (y >= max_y) return false;
7138
7139
4/4
✓ Branch 0 taken 30758247 times.
✓ Branch 1 taken 106210613 times.
✓ Branch 2 taken 100449289 times.
✓ Branch 3 taken 5761324 times.
136968860 return _walkflag_new(x, y, standing_z_state) || (cnt != 1 && _walkflag_new(x + 8, y, standing_z_state));
7140 138202307 }
7141
7142 105138814 static bool effectflag(int32_t x, int32_t y, int32_t layer)
7143 {
7144 105138814 mapscr* s0 = get_scr_for_world_xy(x, y);
7145 105138814 mapscr* s1 = get_scr_for_world_xy_layer(x, y, 1);
7146 105138814 mapscr* s2 = get_scr_for_world_xy_layer(x, y, 2);
7147
2/2
✓ Branch 0 taken 57655235 times.
✓ Branch 1 taken 47483579 times.
105138814 if (!s1->valid) s1 = s0;
7148
2/2
✓ Branch 0 taken 24622036 times.
✓ Branch 1 taken 80516778 times.
105138814 if (!s2->valid) s2 = s0;
7149
7150 105138814 int pos = COMBOPOS(x % 256, y % 176);
7151 105138814 const newcombo& c = combobuf[s0->data[pos]];
7152 105138814 const newcombo& c1 = combobuf[s1->data[pos]];
7153 105138814 const newcombo& c2 = combobuf[s2->data[pos]];
7154
4/4
✓ Branch 0 taken 104143110 times.
✓ Branch 1 taken 995704 times.
✓ Branch 2 taken 104141830 times.
✓ Branch 3 taken 1280 times.
210277628 bool dried = (((iswater_type(c.type)) || (iswater_type(c1.type)) ||
7155
3/4
✗ Branch 0 not taken.
✓ Branch 1 taken 104141830 times.
✓ Branch 2 taken 995300 times.
✓ Branch 3 taken 1684 times.
105138814 (iswater_type(c2.type))) && DRIEDLAKE);
7156 105138814 int32_t b=1;
7157
2/2
✓ Branch 0 taken 53207340 times.
✓ Branch 1 taken 51931474 times.
105138814 if(x&8) b<<=2;
7158
2/2
✓ Branch 0 taken 44691957 times.
✓ Branch 1 taken 60446857 times.
105138814 if(y&8) b<<=1;
7159
7160 105138814 int32_t cwalkflag = (c.walk>>4);
7161
2/2
✓ Branch 0 taken 80373945 times.
✓ Branch 1 taken 24764869 times.
105138814 if (layer == 0) cwalkflag = (c1.walk>>4);
7162
2/2
✓ Branch 0 taken 80375539 times.
✓ Branch 1 taken 24763275 times.
105138814 if (layer == 1) cwalkflag = (c2.walk>>4);
7163 //if (c.type == cBRIDGE || (iswater_type(c.type) && ((c.usrflags&cflag3) || (c.usrflags&cflag4)))) cwalkflag = 0;
7164
4/4
✓ Branch 0 taken 57655235 times.
✓ Branch 1 taken 47483579 times.
✓ Branch 2 taken 24571560 times.
✓ Branch 3 taken 33083675 times.
105138814 if (s1 != s0 && layer < 0)
7165 {
7166
2/2
✓ Branch 0 taken 24555346 times.
✓ Branch 1 taken 16214 times.
24571560 if (c1.type == cBRIDGE) cwalkflag &= (~(c1.walk>>4));
7167 24571560 }
7168
4/4
✓ Branch 0 taken 24622036 times.
✓ Branch 1 taken 80516778 times.
✓ Branch 2 taken 17773115 times.
✓ Branch 3 taken 6848921 times.
105138814 if (s2 != s0 && layer < 1)
7169 {
7170
2/2
✓ Branch 0 taken 17761231 times.
✓ Branch 1 taken 11884 times.
17773115 if (c2.type == cBRIDGE) cwalkflag &= (~(c2.walk>>4));
7171 17773115 }
7172
7173
2/2
✓ Branch 0 taken 104960810 times.
✓ Branch 1 taken 178004 times.
105138814 return (cwalkflag&b) ? !dried : false;
7174 }
7175
7176 105512138 bool _effectflag(int32_t x,int32_t y,int32_t cnt, int32_t layer, bool notLink)
7177 {
7178 DCHECK(cnt == 0 || cnt == 1);
7179 105512138 int max_x = world_w;
7180 105512138 int max_y = world_h;
7181
3/4
✓ Branch 0 taken 45833723 times.
✓ Branch 1 taken 59678415 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 45833723 times.
105512138 if (!get_qr(qr_LTTPWALK) && !notLink)
7182 {
7183 45833723 max_x -= 7;
7184 45833723 max_y -= 7;
7185 45833723 }
7186
4/4
✓ Branch 0 taken 105511386 times.
✓ Branch 1 taken 752 times.
✓ Branch 2 taken 204 times.
✓ Branch 3 taken 105511182 times.
105512138 if (x < 0 || y < 0) return false;
7187
2/2
✓ Branch 0 taken 816 times.
✓ Branch 1 taken 105510366 times.
105511182 if (x >= max_x) return false;
7188
3/4
✓ Branch 0 taken 526426 times.
✓ Branch 1 taken 104983940 times.
✓ Branch 2 taken 526426 times.
✗ Branch 3 not taken.
105510366 if (x >= max_x - 8 && cnt == 2) return false;
7189
2/2
✓ Branch 0 taken 371552 times.
✓ Branch 1 taken 105138814 times.
105510366 if (y >= max_y) return false;
7190
7191
3/4
✓ Branch 0 taken 104960020 times.
✓ Branch 1 taken 178794 times.
✓ Branch 2 taken 178794 times.
✗ Branch 3 not taken.
105138814 return effectflag(x, y, layer) || (cnt == 2 && effectflag(x + 8, y, layer));
7192 105512138 }
7193
7194 // used by mapdata->isSolid(x,y) in ZScript
7195 bool _walkflag(zfix_round zx,zfix_round zy,int32_t cnt, mapscr* m)
7196 {
7197 int x = zx.getRound(), y = zy.getRound();
7198 {
7199 int max_x = 256;
7200 int max_y = 176;
7201 if (!get_qr(qr_LTTPWALK))
7202 {
7203 max_x -= 7;
7204 max_y -= 7;
7205 }
7206 if (x < 0 || y < 0) return false;
7207 if (x >= max_x) return false;
7208 if (x >= max_x - 8 && cnt == 2) return false;
7209 if (y >= max_y) return false;
7210 }
7211
7212 const mapscr *s1, *s2;
7213 s1 = s2 = m;
7214
7215 if ( m->layermap[0] > 0 && m->layermap[0] <= map_count )
7216 {
7217 const mapscr* s = get_canonical_scr(m->layermap[0] - 1, m->layerscreen[0]);
7218 if (s->is_valid())
7219 s1 = s;
7220 }
7221
7222 if ( m->layermap[1] > 0 && m->layermap[1] <= map_count )
7223 {
7224 const mapscr* s = get_canonical_scr(m->layermap[1] - 1, m->layerscreen[1]);
7225 if (s->is_valid())
7226 s2 = s;
7227 }
7228
7229 zfix unused;
7230 return _walkflag_new(m, s1, s2, x, y, unused, false) || (cnt != 1 && _walkflag_new(m, s1, s2, x + 8, y, unused, false));
7231 }
7232
7233 bool _walkflag_layer(zfix_round x, zfix_round y, int32_t layer, int32_t cnt)
7234 {
7235 DCHECK_LAYER_NEG1_INDEX(layer);
7236 mapscr* m = get_scr_for_world_xy_layer(x, y, layer + 1);
7237 if (!m->is_valid()) return false;
7238 return _walkflag_layer(x, y, cnt, m);
7239 }
7240
7241 static bool _walkflag_layer_new(zfix_round zx,zfix_round zy,int32_t cnt, mapscr* m, int max_x, int max_y)
7242 {
7243 int x = zx.getRound(), y = zy.getRound();
7244
7245 if (!get_qr(qr_LTTPWALK))
7246 {
7247 max_x -= 7;
7248 max_y -= 7;
7249 }
7250 if (x < 0 || y < 0) return false;
7251 if (x >= max_x) return false;
7252 if (x >= max_x - 8 && cnt == 2) return false;
7253 if (y >= max_y) return false;
7254
7255 if(!m) return true;
7256
7257 int pos = COMBOPOS(x%256, y%176);
7258 const newcombo* c = &combobuf[m->data[pos]];
7259 bool dried = ((iswater_type(c->type)) && DRIEDLAKE);
7260 int32_t b=1;
7261
7262 if(x&8) b<<=2;
7263
7264 if(y&8) b<<=1;
7265
7266 if((c->walk&b) && !dried)
7267 return true;
7268
7269 if(cnt==1) return false;
7270
7271 ++pos;
7272
7273 if(!(x&8))
7274 b<<=2;
7275 else
7276 {
7277 c = &combobuf[m->data[pos]];
7278 dried = ((iswater_type(c->type)) && DRIEDLAKE);
7279 b=1;
7280
7281 if(y&8) b<<=1;
7282 }
7283
7284 return (c->walk&b) ? !dried : false;
7285 }
7286
7287 //Only check the given mapscr*, not its layer 1&2
7288 bool _walkflag_layer(zfix_round zx,zfix_round zy,int32_t cnt, mapscr* m)
7289 {
7290 return _walkflag_layer_new(zx, zy, cnt, m, world_w, world_h);
7291 }
7292
7293 bool _walkflag_layer_scrolling(zfix_round zx,zfix_round zy,int32_t cnt, mapscr* m)
7294 {
7295 return _walkflag_layer_new(zx, zy, cnt, m, scrolling_region.width, scrolling_region.height);
7296 }
7297
7298 447898 bool _effectflag_layer(int32_t x, int32_t y, int32_t layer, int32_t cnt, bool notLink)
7299 {
7300 DCHECK_LAYER_NEG1_INDEX(layer);
7301 447898 mapscr* m = get_scr_for_world_xy_layer(x, y, layer + 1);
7302
2/2
✓ Branch 0 taken 1762 times.
✓ Branch 1 taken 446136 times.
447898 if (!m->is_valid()) return false;
7303 446136 return _effectflag_layer(x, y, cnt, m, notLink);
7304 447898 }
7305
7306 519213 bool _effectflag_layer(int32_t x,int32_t y,int32_t cnt, mapscr* m, bool notLink)
7307 {
7308 519213 int max_x = world_w;
7309 519213 int max_y = world_h;
7310
3/4
✓ Branch 0 taken 50002 times.
✓ Branch 1 taken 469211 times.
✓ Branch 2 taken 50002 times.
✗ Branch 3 not taken.
519213 if (!get_qr(qr_LTTPWALK) && !notLink)
7311 {
7312 max_x -= 7;
7313 max_y -= 7;
7314 }
7315
2/4
✓ Branch 0 taken 519213 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 519213 times.
519213 if (x < 0 || y < 0) return false;
7316
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 519213 times.
519213 if (x >= max_x) return false;
7317
3/4
✓ Branch 0 taken 1342 times.
✓ Branch 1 taken 517871 times.
✓ Branch 2 taken 1342 times.
✗ Branch 3 not taken.
519213 if (x >= max_x - 8 && cnt == 2) return false;
7318
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 519213 times.
519213 if (y >= max_y) return false;
7319
7320
1/2
✓ Branch 0 taken 519213 times.
✗ Branch 1 not taken.
519213 if (!m) return true;
7321
7322 519213 int pos = COMBOPOS(x%256, y%176);
7323 519213 const newcombo* c = &combobuf[m->data[pos]];
7324
3/4
✓ Branch 0 taken 518813 times.
✓ Branch 1 taken 400 times.
✓ Branch 2 taken 400 times.
✗ Branch 3 not taken.
519613 bool dried = ((iswater_type(c->type)) && DRIEDLAKE);
7325 519213 int32_t b=1;
7326
7327
2/2
✓ Branch 0 taken 276528 times.
✓ Branch 1 taken 242685 times.
519213 if(x&8) b<<=2;
7328
7329
2/2
✓ Branch 0 taken 220331 times.
✓ Branch 1 taken 298882 times.
519213 if(y&8) b<<=1;
7330
7331
3/4
✓ Branch 0 taken 450224 times.
✓ Branch 1 taken 68989 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 450224 times.
519213 if(((c->walk>>4)&b) && !dried)
7332 450224 return true;
7333
7334
1/2
✓ Branch 0 taken 68989 times.
✗ Branch 1 not taken.
68989 if(cnt==1) return false;
7335
7336 ++pos;
7337
7338 if(!(x&8))
7339 b<<=2;
7340 else
7341 {
7342 c = &combobuf[m->data[pos]];
7343 dried = ((iswater_type(c->type)) && DRIEDLAKE);
7344 b=1;
7345
7346 if(y&8) b<<=1;
7347 }
7348
7349 return ((c->walk>>4)&b) ? !dried : false;
7350 519213 }
7351
7352 860420 bool water_walkflag(int32_t x, int32_t y, int32_t cnt)
7353 {
7354 860420 int max_x = world_w;
7355 860420 int max_y = world_h;
7356
2/2
✓ Branch 0 taken 165182 times.
✓ Branch 1 taken 695238 times.
860420 if (!get_qr(qr_LTTPWALK))
7357 {
7358 695238 max_x -= 7;
7359 695238 max_y -= 7;
7360 695238 }
7361
2/4
✓ Branch 0 taken 860420 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 860420 times.
860420 if (x < 0 || y < 0) return false;
7362
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 860420 times.
860420 if (x >= max_x) return false;
7363
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 860420 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
860420 if (x >= max_x - 8 && cnt == 2) return false;
7364
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 860420 times.
860420 if (y >= max_y) return false;
7365
7366
3/4
✓ Branch 0 taken 17860 times.
✓ Branch 1 taken 842560 times.
✓ Branch 2 taken 842560 times.
✗ Branch 3 not taken.
860420 return water_walkflag(x, y) || (cnt != 1 && water_walkflag(x + 8, y));
7367 860420 }
7368
7369 860420 bool water_walkflag(int32_t x, int32_t y)
7370 {
7371 860420 const newcombo& c = combobuf[MAPCOMBO2(-1, x, y)];
7372 860420 const newcombo& c1 = combobuf[MAPCOMBO2(0, x, y)];
7373 860420 const newcombo& c2 = combobuf[MAPCOMBO2(1, x, y)];
7374
7375 860420 int32_t b=1;
7376
2/2
✓ Branch 0 taken 439102 times.
✓ Branch 1 taken 421318 times.
860420 if(x&8) b<<=2;
7377
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 860420 times.
860420 if(y&8) b<<=1;
7378
7379
2/2
✓ Branch 0 taken 74192 times.
✓ Branch 1 taken 786228 times.
860420 if(get_qr(qr_NO_SOLID_SWIM))
7380 {
7381
2/2
✓ Branch 0 taken 474 times.
✓ Branch 1 taken 73718 times.
74192 if(c.walk&b)
7382 474 return true;
7383
7384
2/2
✓ Branch 0 taken 914 times.
✓ Branch 1 taken 72804 times.
73718 if(c1.walk&b)
7385 914 return true;
7386
7387
2/2
✓ Branch 0 taken 71 times.
✓ Branch 1 taken 72733 times.
72804 if(c2.walk&b)
7388 71 return true;
7389 72733 }
7390 else
7391 {
7392
4/4
✓ Branch 0 taken 36133 times.
✓ Branch 1 taken 750095 times.
✓ Branch 2 taken 19762 times.
✓ Branch 3 taken 16371 times.
786228 if((c.walk&b) && !iswater_type(c.type))
7393 16371 return true;
7394
7395
3/4
✓ Branch 0 taken 17 times.
✓ Branch 1 taken 769840 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 17 times.
769857 if((c1.walk&b) && !iswater_type(c1.type))
7396 17 return true;
7397
7398
3/4
✓ Branch 0 taken 13 times.
✓ Branch 1 taken 769827 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 13 times.
769840 if((c2.walk&b) && !iswater_type(c2.type))
7399 13 return true;
7400 }
7401
7402 842560 return false;
7403 860420 }
7404
7405 589885 bool hit_walkflag(int32_t x,int32_t y,int32_t cnt)
7406 {
7407
2/2
✓ Branch 0 taken 100391 times.
✓ Branch 1 taken 489494 times.
589885 if(dlevel)
7408
8/8
✓ Branch 0 taken 488049 times.
✓ Branch 1 taken 1445 times.
✓ Branch 2 taken 484722 times.
✓ Branch 3 taken 3327 times.
✓ Branch 4 taken 483005 times.
✓ Branch 5 taken 1717 times.
✓ Branch 6 taken 4386 times.
✓ Branch 7 taken 478619 times.
489494 if(x<32 || y<40 || (x+(cnt-1)*8)>=world_w-32 || y>=world_h-32)
7409 10875 return true;
7410
7411
3/4
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 579008 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
579010 if(blockpath && y<((get_qr(qr_LTTPCOLLISION))?80:88))
7412 return true;
7413
7414
8/8
✓ Branch 0 taken 578724 times.
✓ Branch 1 taken 286 times.
✓ Branch 2 taken 578481 times.
✓ Branch 3 taken 243 times.
✓ Branch 4 taken 578270 times.
✓ Branch 5 taken 211 times.
✓ Branch 6 taken 396 times.
✓ Branch 7 taken 577874 times.
579010 if(x<16 || y<16 || (x+(cnt-1)*8)>=world_w-16 || y>=world_h-16)
7415 1136 return true;
7416
7417 // for(int32_t i=0; i<4; i++)
7418
4/4
✓ Branch 0 taken 841 times.
✓ Branch 1 taken 577033 times.
✓ Branch 2 taken 36 times.
✓ Branch 3 taken 805 times.
577874 if(mblock2.clk && mblock2.hit(x,y,0,cnt*8,1,16))
7419 36 return true;
7420
7421
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 577837 times.
577838 if (collide_object(x, y,cnt*8, 1))
7422 1 return true;
7423
7424 577837 return _walkflag(x,y,cnt);
7425 589885 }
7426
7427 12220 bool solpush_walkflag(int32_t x, int32_t y, int32_t cnt, solid_object const* ign)
7428 {
7429 // 16 pixel buffer to account for slopes that are on bordering screens.
7430
4/8
✓ Branch 0 taken 12220 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12220 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 12220 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 12220 times.
12220 if(x<0 || y<0 || x>=world_w+16 || y>=world_h+16)
7431 return true;
7432
7433 // for(int32_t i=0; i<4; i++)
7434
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 12220 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
12220 if(mblock2.clk && mblock2.hit(x,y,0,cnt*8,1,16))
7435 return true;
7436
7437
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 12220 times.
12220 if (collide_object(x, y,cnt*8, 1, ign))
7438 return true;
7439
7440 12220 return _walkflag(x,y,cnt);
7441 12220 }
7442
7443 39588 void map_bkgsfx(bool on)
7444 {
7445
2/2
✓ Branch 0 taken 39567 times.
✓ Branch 1 taken 21 times.
39588 if(on)
7446 {
7447 39567 cont_sfx(hero_scr->oceansfx);
7448
7449
4/4
✓ Branch 0 taken 369 times.
✓ Branch 1 taken 39198 times.
✓ Branch 2 taken 315 times.
✓ Branch 3 taken 54 times.
39567 if(hero_scr->bosssfx && !(game->lvlitems[dlevel]&(1 << li_boss_killed)))
7450 315 cont_sfx(hero_scr->bosssfx);
7451 39567 }
7452 else
7453 {
7454 21 adjust_sfx(hero_scr->oceansfx,128,false);
7455 21 adjust_sfx(hero_scr->bosssfx,128,false);
7456
7457
2/2
✓ Branch 0 taken 114 times.
✓ Branch 1 taken 21 times.
135 for(int32_t i=0; i<guys.Count(); i++)
7458 {
7459
2/2
✓ Branch 0 taken 30 times.
✓ Branch 1 taken 84 times.
114 if(((enemy*)guys.spr(i))->bgsfx)
7460 84 stop_sfx(((enemy*)guys.spr(i))->bgsfx);
7461 114 }
7462 }
7463 39588 }
7464
7465 261 void toggle_switches(dword flags, bool entry)
7466 {
7467
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 261 times.
261 if(!flags) return; //No flags to toggle
7468
7469 522 for_every_base_screen_in_region([&](mapscr* scr, unsigned int region_scr_x, unsigned int region_scr_y) {
7470 261 toggle_switches(flags, entry, create_screen_handles(scr));
7471 261 });
7472 261 }
7473 55204 void toggle_switches(dword flags, bool entry, const screen_handles_t& screen_handles)
7474 {
7475
2/2
✓ Branch 0 taken 931 times.
✓ Branch 1 taken 54273 times.
55204 if(!flags) return; //No flags to toggle
7476
7477 931 mapscr* m = screen_handles[0].base_scr;
7478 931 int screen = m->screen;
7479 931 bool is_active_screen = is_in_current_region(m);
7480
7481 525235 for_every_rpos_in_screen(screen_handles, [&](const rpos_handle_t& rpos_handle) {
7482 524304 byte togglegrid[176] = {0};
7483 524304 mapscr* scr = rpos_handle.scr;
7484 524304 int lyr = rpos_handle.layer;
7485 524304 int pos = rpos_handle.pos;
7486 524304 newcombo const& cmb = combobuf[scr->data[pos]];
7487
2/2
✓ Branch 0 taken 39424 times.
✓ Branch 1 taken 484880 times.
524304 if(is_active_screen)
7488
1/2
✓ Branch 0 taken 484880 times.
✗ Branch 1 not taken.
641011 trig_each_combo_trigger(rpos_handle, [&](combo_trigger const& trig){
7489
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 156131 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
156131 return trig.trigger_flags.get(TRIGFLAG_TRIGLEVELSTATE) && trig.trig_lstate < 32 && (flags&(1<<trig.trig_lstate));
7490 }, ctrigSWITCHSTATE);
7491
3/4
✓ Branch 0 taken 523592 times.
✓ Branch 1 taken 712 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2809 times.
524304 if((cmb.type == cCSWITCH || cmb.type == cCSWITCHBLOCK) && cmb.attribytes[0] < 32
7492
2/2
✓ Branch 0 taken 2809 times.
✓ Branch 1 taken 521495 times.
524304 && !(cmb.usrflags & cflag11)) //global state
7493 {
7494
2/2
✓ Branch 0 taken 446 times.
✓ Branch 1 taken 2363 times.
2809 if(flags&(1<<cmb.attribytes[0]))
7495 {
7496 2363 set<int32_t> oldData;
7497 //Increment the combo/cset by the attributes
7498 2363 int32_t cmbofs = (cmb.attributes[0]/10000L);
7499 2363 int32_t csofs = (cmb.attributes[1]/10000L);
7500
1/2
✓ Branch 0 taken 2363 times.
✗ Branch 1 not taken.
2363 oldData.insert(scr->data[pos]);
7501
1/2
✓ Branch 0 taken 2363 times.
✗ Branch 1 not taken.
2363 scr->data[pos] = BOUND_COMBO(scr->data[pos] + cmbofs);
7502 2363 scr->cset[pos] = (scr->cset[pos] + csofs) & 15;
7503
4/4
✓ Branch 0 taken 1444 times.
✓ Branch 1 taken 919 times.
✓ Branch 2 taken 1206 times.
✓ Branch 3 taken 238 times.
2363 if(entry && (cmb.usrflags&cflag8))
7504 {
7505 238 newcombo const* tmp = &combobuf[scr->data[pos]];
7506
2/4
✓ Branch 0 taken 238 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 238 times.
✗ Branch 3 not taken.
238 while(tmp->can_cycle())
7507 {
7508 bool cycle_under = (tmp->animflags & AF_CYCLEUNDERCOMBO);
7509 auto cid = cycle_under ? scr->undercombo : tmp->nextcombo;
7510 if(oldData.find(cid) != oldData.end())
7511 break;
7512
7513 scr->data[pos] = cid;
7514 if(!(tmp->animflags & AF_CYCLENOCSET))
7515 scr->cset[pos] = cycle_under ? scr->undercset : tmp->nextcset;
7516 oldData.insert(cid);
7517 tmp = &combobuf[cid];
7518 }
7519 238 }
7520 2363 int32_t cmbid = scr->data[pos];
7521
2/2
✓ Branch 0 taken 41 times.
✓ Branch 1 taken 2322 times.
2363 if(combobuf[cmbid].animflags & AF_CYCLE)
7522 {
7523 41 combobuf[cmbid].tile = combobuf[cmbid].o_tile;
7524 41 combobuf[cmbid].cur_frame=0;
7525 41 combobuf[cmbid].aclk = 0;
7526
1/2
✓ Branch 0 taken 41 times.
✗ Branch 1 not taken.
41 combo_caches::drawing.refresh(cmbid);
7527 41 }
7528 2363 togglegrid[pos] |= (1<<lyr); //Mark this pos toggled for this layer
7529
2/2
✓ Branch 0 taken 560 times.
✓ Branch 1 taken 1803 times.
2363 if(cmb.type == cCSWITCH) return; //Switches don't toggle other layers
7530
2/2
✓ Branch 0 taken 12621 times.
✓ Branch 1 taken 1803 times.
14424 for(int32_t lyr2 = 0; lyr2 < 7; ++lyr2) //Toggle same pos on other layers, if flag set
7531 {
7532
2/2
✓ Branch 0 taken 1803 times.
✓ Branch 1 taken 10818 times.
12621 if(lyr==lyr2) continue;
7533
2/2
✓ Branch 0 taken 344 times.
✓ Branch 1 taken 10474 times.
10818 if(!(cmb.usrflags&(1<<lyr2))) continue;
7534
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 344 times.
344 if(togglegrid[pos]&(1<<lyr2)) continue;
7535
7536 344 mapscr* scr_2 = screen_handles[lyr2].scr;
7537
1/2
✓ Branch 0 taken 344 times.
✗ Branch 1 not taken.
344 if(!scr_2->data[pos]) //Don't increment empty space
7538 continue;
7539 344 newcombo const& cmb_2 = combobuf[scr_2->data[pos]];
7540
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 344 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
344 if(lyr2 > lyr && (cmb_2.type == cCSWITCH || cmb_2.type == cCSWITCHBLOCK) && !(cmb.usrflags & cflag11)
7541 && cmb_2.attribytes[0] < 32 && (flags&(1<<cmb_2.attribytes[0])))
7542 continue; //This is a switch/block that will be hit later in the loop!
7543 344 set<int32_t> oldData2;
7544 //Increment the combo/cset by the original cmb's attributes
7545
1/2
✓ Branch 0 taken 344 times.
✗ Branch 1 not taken.
344 oldData2.insert(scr_2->data[pos]);
7546
1/2
✓ Branch 0 taken 344 times.
✗ Branch 1 not taken.
344 scr_2->data[pos] = BOUND_COMBO(scr_2->data[pos] + cmbofs);
7547 344 scr_2->cset[pos] = (scr_2->cset[pos] + csofs) & 15;
7548
3/4
✓ Branch 0 taken 50 times.
✓ Branch 1 taken 294 times.
✓ Branch 2 taken 50 times.
✗ Branch 3 not taken.
344 if(entry && (cmb.usrflags&cflag8)) //Skip cycling on screen entry
7549 {
7550 newcombo const* tmp = &combobuf[scr_2->data[pos]];
7551 while(tmp->can_cycle())
7552 {
7553 bool cycle_under = (tmp->animflags & AF_CYCLEUNDERCOMBO);
7554 auto cid = cycle_under ? scr_2->undercombo : tmp->nextcombo;
7555 if(oldData2.find(cid) != oldData2.end())
7556 break;
7557
7558 scr_2->data[pos] = cid;
7559 if(!(tmp->animflags & AF_CYCLENOCSET))
7560 scr_2->cset[pos] = cycle_under ? scr_2->undercset : tmp->nextcset;
7561 oldData2.insert(cid);
7562 tmp = &combobuf[cid];
7563 }
7564 }
7565 344 int32_t cmbid2 = scr_2->data[pos];
7566
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 344 times.
344 if(combobuf[cmbid2].animflags & AF_CYCLE)
7567 {
7568 combobuf[cmbid2].tile = combobuf[cmbid2].o_tile;
7569 combobuf[cmbid2].cur_frame=0;
7570 combobuf[cmbid2].aclk = 0;
7571 combo_caches::drawing.refresh(cmbid2);
7572 }
7573 344 togglegrid[pos] |= (1<<lyr2); //Mark this pos toggled for this layer
7574 344 }
7575
2/3
✗ Branch 0 not taken.
✓ Branch 1 taken 560 times.
✓ Branch 2 taken 1803 times.
2363 }
7576 2249 }
7577 524304 });
7578
7579
3/4
✓ Branch 0 taken 519 times.
✓ Branch 1 taken 412 times.
✓ Branch 2 taken 519 times.
✗ Branch 3 not taken.
931 if(get_qr(qr_SWITCHES_AFFECT_MOVINGBLOCKS) && mblock2.clk)
7580 {
7581 newcombo const& cmb = combobuf[mblock2.bcombo];
7582 if(!(cmb.usrflags & cflag11) && (cmb.type == cCSWITCH || cmb.type == cCSWITCHBLOCK) && cmb.attribytes[0] < 32)
7583 {
7584 if(flags&(1<<cmb.attribytes[0]))
7585 {
7586 //Increment the combo/cset by the attributes
7587 int32_t cmbofs = (cmb.attributes[0]/10000L);
7588 int32_t csofs = (cmb.attributes[1]/10000L);
7589 mblock2.bcombo = BOUND_COMBO(mblock2.bcombo + cmbofs);
7590 mblock2.cs = (mblock2.cs + csofs) & 15;
7591 int32_t cmbid = mblock2.bcombo;
7592 if(combobuf[cmbid].animflags & AF_CYCLE)
7593 {
7594 combobuf[cmbid].tile = combobuf[cmbid].o_tile;
7595 combobuf[cmbid].cur_frame=0;
7596 combobuf[cmbid].aclk = 0;
7597 combo_caches::drawing.refresh(cmbid);
7598 }
7599 }
7600 }
7601 }
7602
7603
2/2
✓ Branch 0 taken 224 times.
✓ Branch 1 taken 707 times.
931 if (is_active_screen)
7604 {
7605 707 int screen_index_offset = get_region_screen_offset(m->screen);
7606 707 word c = m->numFFC();
7607
2/2
✓ Branch 0 taken 565 times.
✓ Branch 1 taken 707 times.
1272 for (int q = 0; q < c; ++q)
7608 {
7609 565 auto ffc_handle = *m->getFFCHandle(q, screen_index_offset);
7610
1/2
✓ Branch 0 taken 565 times.
✗ Branch 1 not taken.
596 trig_each_combo_trigger(ffc_handle, [&](combo_trigger const& trig){
7611
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 31 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
31 return trig.trigger_flags.get(TRIGFLAG_TRIGLEVELSTATE) && trig.trig_lstate < 32 && (flags&(1<<trig.trig_lstate));
7612 }, ctrigSWITCHSTATE);
7613 565 }
7614 707 }
7615 55204 }
7616
7617 1 void toggle_gswitches(int32_t state, bool entry)
7618 {
7619 2 for_every_base_screen_in_region([&](mapscr* scr, unsigned int region_scr_x, unsigned int region_scr_y) {
7620 1 toggle_gswitches(state, entry, create_screen_handles(scr));
7621 1 });
7622 1 }
7623 1 void toggle_gswitches(int32_t state, bool entry, const screen_handles_t& screen_handles)
7624 {
7625 1 bool states[256] = {false};
7626 1 states[state] = true;
7627 1 toggle_gswitches(states, entry, screen_handles);
7628 1 }
7629 15792894 void toggle_gswitches(bool* states, bool entry, const screen_handles_t& screen_handles)
7630 {
7631
1/2
✓ Branch 0 taken 15792894 times.
✗ Branch 1 not taken.
15792894 if(!states) return;
7632
7633 15792894 auto& combo_cache = combo_caches::gswitch;
7634 15792894 mapscr* base_scr = screen_handles[0].base_scr;
7635 15792894 int screen = base_scr->screen;
7636 15792894 bool is_active_screen = is_in_current_region(base_scr);
7637 15792894 byte togglegrid[176] = {0};
7638
2/2
✓ Branch 0 taken 15792894 times.
✓ Branch 1 taken 110550258 times.
126343152 for(int32_t lyr = 0; lyr <= 6; ++lyr)
7639 {
7640 110550258 mapscr* scr = screen_handles[lyr].scr;
7641
2/2
✓ Branch 0 taken 35895920 times.
✓ Branch 1 taken 74654338 times.
110550258 if (!scr)
7642 74654338 continue;
7643
7644
2/2
✓ Branch 0 taken 35895920 times.
✓ Branch 1 taken 6317681920 times.
6353577840 for(int32_t pos = 0; pos < 176; ++pos)
7645 {
7646 6317681920 int cid = scr->data[pos];
7647 6317681920 auto& mini_cmb = combo_cache.minis[cid];
7648
7649
2/2
✓ Branch 0 taken 2910336 times.
✓ Branch 1 taken 6314771584 times.
6317681920 if (is_active_screen)
7650 {
7651
2/2
✓ Branch 0 taken 6314769702 times.
✓ Branch 1 taken 1882 times.
6314771584 if (mini_cmb.trigger_global_state)
7652 {
7653 1882 auto rpos_handle = get_rpos_handle_for_screen(screen, lyr, pos);
7654
1/2
✓ Branch 0 taken 1882 times.
✗ Branch 1 not taken.
3764 trig_each_combo_trigger(rpos_handle, [&](combo_trigger const& trig){
7655
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1882 times.
1882 return trig.trigger_flags.get(TRIGFLAG_TRIGGLOBALSTATE) && states[trig.trig_gstate];
7656 }, ctrigSWITCHSTATE);
7657 1882 }
7658 6314771584 }
7659
7660
2/2
✓ Branch 0 taken 55356 times.
✓ Branch 1 taken 6317626564 times.
6317681920 if (!mini_cmb.has_global_state)
7661 6317626564 continue;
7662
7663 55356 newcombo const& cmb = combobuf[cid];
7664
2/4
✓ Branch 0 taken 55356 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 55356 times.
55356 if(cmb.type == cCSWITCH || cmb.type == cCSWITCHBLOCK)
7665 {
7666 if(states[cmb.attribytes[0]])
7667 {
7668 set<int32_t> oldData;
7669 //Increment the combo/cset by the attributes
7670 int32_t cmbofs = (cmb.attributes[0]/10000L);
7671 int32_t csofs = (cmb.attributes[1]/10000L);
7672 oldData.insert(scr->data[pos]);
7673 scr->data[pos] = BOUND_COMBO(scr->data[pos] + cmbofs);
7674 scr->cset[pos] = (scr->cset[pos] + csofs) & 15;
7675 if(entry && (cmb.usrflags&cflag8))
7676 {
7677 newcombo const* tmp = &combobuf[scr->data[pos]];
7678 while(tmp->can_cycle())
7679 {
7680 bool cycle_under = (tmp->animflags & AF_CYCLEUNDERCOMBO);
7681 auto cid = cycle_under ? scr->undercombo : tmp->nextcombo;
7682 if(oldData.find(cid) != oldData.end())
7683 break;
7684 scr->data[pos] = cid;
7685 if(!(tmp->animflags & AF_CYCLENOCSET))
7686 scr->cset[pos] = cycle_under ? scr->undercset : tmp->nextcset;
7687 oldData.insert(cid);
7688 tmp = &combobuf[cid];
7689 }
7690 }
7691 int32_t cmbid = scr->data[pos];
7692 if(combobuf[cmbid].animflags & AF_CYCLE)
7693 {
7694 combobuf[cmbid].tile = combobuf[cmbid].o_tile;
7695 combobuf[cmbid].cur_frame=0;
7696 combobuf[cmbid].aclk = 0;
7697 combo_caches::drawing.refresh(cmbid);
7698 }
7699 togglegrid[pos] |= (1<<lyr); //Mark this pos toggled for this layer
7700 if(cmb.type == cCSWITCH) continue; //Switches don't toggle other layers
7701 for(int32_t lyr2 = 0; lyr2 <= 6; ++lyr2) //Toggle same pos on other layers, if flag set
7702 {
7703 if(lyr==lyr2) continue;
7704 if(!(cmb.usrflags&(1<<lyr2))) continue;
7705 if(togglegrid[pos]&(1<<lyr2)) continue;
7706 mapscr* scr_2 = lyr2 == 0 ? base_scr : get_scr_layer_valid(screen, lyr2);
7707 if(!scr_2 || !scr_2->data[pos]) //Don't increment empty space
7708 continue;
7709 newcombo const& cmb_2 = combobuf[scr_2->data[pos]];
7710 if(lyr2 > lyr && (cmb_2.type == cCSWITCH || cmb_2.type == cCSWITCHBLOCK)
7711 && (cmb_2.usrflags & cflag11) && (states[cmb_2.attribytes[0]]))
7712 continue; //This is a switch/block that will be hit later in the loop!
7713 set<int32_t> oldData2;
7714 //Increment the combo/cset by the original cmb's attributes
7715 oldData2.insert(scr_2->data[pos]);
7716 scr_2->data[pos] = BOUND_COMBO(scr_2->data[pos] + cmbofs);
7717 scr_2->cset[pos] = (scr_2->cset[pos] + csofs) & 15;
7718 if(entry && (cmb.usrflags&cflag8)) //Skip cycling on screen entry
7719 {
7720 newcombo const* tmp = &combobuf[scr_2->data[pos]];
7721 while(tmp->can_cycle())
7722 {
7723 bool cycle_under = (tmp->animflags & AF_CYCLEUNDERCOMBO);
7724 auto cid = cycle_under ? scr_2->undercombo : tmp->nextcombo;
7725 if(oldData2.find(cid) != oldData2.end())
7726 break;
7727 scr_2->data[pos] = cid;
7728 if(!(tmp->animflags & AF_CYCLENOCSET))
7729 scr_2->cset[pos] = cycle_under ? scr_2->undercset : tmp->nextcset;
7730 oldData2.insert(cid);
7731 tmp = &combobuf[cid];
7732 }
7733 }
7734 int32_t cmbid2 = scr_2->data[pos];
7735 if(combobuf[cmbid2].animflags & AF_CYCLE)
7736 {
7737 combobuf[cmbid2].tile = combobuf[cmbid2].o_tile;
7738 combobuf[cmbid2].cur_frame=0;
7739 combobuf[cmbid2].aclk = 0;
7740 combo_caches::drawing.refresh(cmbid2);
7741 }
7742 togglegrid[pos] |= (1<<lyr2); //Mark this pos toggled for this layer
7743 }
7744 }
7745 }
7746 55356 }
7747 35895920 }
7748
7749
4/4
✓ Branch 0 taken 550719 times.
✓ Branch 1 taken 15242175 times.
✓ Branch 2 taken 545975 times.
✓ Branch 3 taken 4744 times.
15792894 if(get_qr(qr_SWITCHES_AFFECT_MOVINGBLOCKS) && mblock2.clk)
7750 {
7751 4744 newcombo const& cmb = combobuf[mblock2.bcombo];
7752
2/4
✓ Branch 0 taken 4744 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4744 times.
✗ Branch 3 not taken.
4744 if((cmb.type == cCSWITCH || cmb.type == cCSWITCHBLOCK) && (cmb.usrflags & cflag11))
7753 {
7754 if(states[cmb.attribytes[0]])
7755 {
7756 //Increment the combo/cset by the attributes
7757 int32_t cmbofs = (cmb.attributes[0]/10000L);
7758 int32_t csofs = (cmb.attributes[1]/10000L);
7759 mblock2.bcombo = BOUND_COMBO(mblock2.bcombo + cmbofs);
7760 mblock2.cs = (mblock2.cs + csofs) & 15;
7761 int32_t cmbid = mblock2.bcombo;
7762 if(combobuf[cmbid].animflags & AF_CYCLE)
7763 {
7764 combobuf[cmbid].tile = combobuf[cmbid].o_tile;
7765 combobuf[cmbid].cur_frame=0;
7766 combobuf[cmbid].aclk = 0;
7767 combo_caches::drawing.refresh(cmbid);
7768 }
7769 }
7770 }
7771 4744 }
7772
7773
2/2
✓ Branch 0 taken 16159 times.
✓ Branch 1 taken 15776735 times.
15792894 if(is_active_screen)
7774 {
7775 15776735 int screen_index_offset = get_region_screen_offset(screen);
7776 15776735 word c = base_scr->numFFC();
7777
2/2
✓ Branch 0 taken 455562886 times.
✓ Branch 1 taken 15776735 times.
471339621 for (int q = 0; q < c; ++q)
7778 {
7779 455562886 auto ffc_handle = *base_scr->getFFCHandle(q, screen_index_offset);
7780
1/2
✓ Branch 0 taken 455562886 times.
✗ Branch 1 not taken.
455796224 trig_each_combo_trigger(ffc_handle, [&](combo_trigger const& trig){
7781
1/2
✓ Branch 0 taken 233338 times.
✗ Branch 1 not taken.
233338 return trig.trigger_flags.get(TRIGFLAG_TRIGGLOBALSTATE) && states[trig.trig_gstate];
7782 }, ctrigSWITCHSTATE);
7783 455562886 }
7784 15776735 }
7785 15792894 }
7786 54943 void toggle_gswitches_load(const screen_handles_t& screen_handles)
7787 {
7788 bool states[256];
7789
2/2
✓ Branch 0 taken 14065408 times.
✓ Branch 1 taken 54943 times.
14120351 for(auto q = 0; q < 256; ++q)
7790 {
7791 14065408 states[q] = game->gswitch_timers[q] != 0;
7792 14065408 }
7793 54943 toggle_gswitches(states, true, screen_handles);
7794 54943 }
7795 15348582 void run_gswitch_timers()
7796 {
7797 15348582 bool states[256] = {false};
7798 15348582 auto& m = game->gswitch_timers.mut_inner();
7799
2/2
✓ Branch 0 taken 3925194752 times.
✓ Branch 1 taken 15348582 times.
3940543334 for(auto it = m.begin(); it != m.end();)
7800 {
7801
2/2
✓ Branch 0 taken 3925194152 times.
✓ Branch 1 taken 600 times.
3925194752 if(it->second > 0)
7802
2/2
✓ Branch 0 taken 599 times.
✓ Branch 1 taken 1 times.
600 if(!--it->second)
7803 {
7804 1 states[it->first] = true;
7805 1 it = m.erase(it);
7806 1 continue;
7807 }
7808 3925194751 ++it;
7809 }
7810 31086532 for_every_base_screen_in_region([&](mapscr* scr, unsigned int region_scr_x, unsigned int region_scr_y) {
7811 15737950 toggle_gswitches(states, false, create_screen_handles(scr));
7812 15737950 });
7813 15348582 }
7814 1149 void onload_gswitch_timers() //Reset all timers that were counting down, no trigger necessary
7815 {
7816
2/2
✓ Branch 0 taken 294144 times.
✓ Branch 1 taken 1149 times.
295293 for(auto q = 0; q < 256; ++q)
7817 {
7818
1/2
✓ Branch 0 taken 294144 times.
✗ Branch 1 not taken.
294144 if(game->gswitch_timers[q] > 0)
7819 game->gswitch_timers[q] = 0;
7820 294144 }
7821 1149 }
7822
7823 /**** View Map ****/
7824
7825 int32_t mapres = 0;
7826 int32_t view_map_show_mode = 3;
7827
7828 129280 bool displayOnMap(int32_t x, int32_t y)
7829 {
7830 129280 int32_t s = (y<<4) + x;
7831 129280 int mi = mapind(cur_map, s);
7832
2/2
✓ Branch 0 taken 70863 times.
✓ Branch 1 taken 58417 times.
129280 if (!(game->maps[mi]&mVISITED))
7833 70863 return false;
7834
7835 // Don't display if not part of DMap
7836
4/4
✓ Branch 0 taken 15807 times.
✓ Branch 1 taken 42610 times.
✓ Branch 2 taken 4750 times.
✓ Branch 3 taken 4311 times.
67478 if(((DMaps[cur_dmap].flags&dmfDMAPMAP) &&
7837
1/2
✓ Branch 0 taken 15807 times.
✗ Branch 1 not taken.
15807 (DMaps[cur_dmap].type != dmOVERW) &&
7838
2/2
✓ Branch 0 taken 12631 times.
✓ Branch 1 taken 3176 times.
15807 !(x >= DMaps[cur_dmap].xoff &&
7839
2/2
✓ Branch 0 taken 9061 times.
✓ Branch 1 taken 3570 times.
12631 x < DMaps[cur_dmap].xoff+8 &&
7840 9061 DMaps[cur_dmap].grid[y]&(128>>(x-DMaps[cur_dmap].xoff)))))
7841 11057 return false;
7842 else
7843 47360 return true;
7844 129280 }
7845
7846 1010 void ViewMap()
7847 {
7848 1010 ViewingMap = true;
7849
7850 1010 BITMAP* mappic = NULL;
7851 static double scales[17] =
7852 {
7853 0.03125, 0.04419, 0.0625, 0.08839, 0.125, 0.177, 0.25, 0.3535,
7854 0.50, 0.707, 1.0, 1.414, 2.0, 2.828, 4.0, 5.657, 8.0
7855 };
7856
7857 // Cursor position for hero, in absolute map coordinates.
7858 1010 int32_t lx = ((cur_screen & 15) << 8) + HeroX() + 8;
7859 1010 int32_t ly = ((cur_screen >> 4) * 176) + HeroY() + 8;
7860
7861 int32_t px;
7862 int32_t py;
7863
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1010 times.
1010 if (is_in_scrolling_region())
7864 {
7865 // Center the player on the middle of the map view.
7866 px = (16*256/2 - lx) * 2;
7867 py = (8*176/2 - ly) * 2;
7868 }
7869 else
7870 {
7871 // Center the current screen on the middle of the map view.
7872 1010 px = ((8-(cur_screen&15)) << 9) - 256;
7873 1010 py = ((4-(cur_screen>>4)) * 352) - 176;
7874 }
7875
7876 1010 int32_t sc = 6;
7877
7878 1010 bool done=false, redraw=true;
7879
7880 1010 mappic = create_bitmap_ex(8,(256*16)>>mapres,(176*8)>>mapres);
7881
7882
1/2
✓ Branch 0 taken 1010 times.
✗ Branch 1 not taken.
1010 if(!mappic)
7883 {
7884 enter_sys_pal();
7885 jwin_alert("View Map","Not enough memory.",NULL,NULL,"OK",NULL,13,27,get_zc_font(font_lfont));
7886 exit_sys_pal();
7887 return;
7888 }
7889
7890 1010 clear_to_color(mappic, WHITE);
7891
7892 1010 auto prev_viewport = viewport;
7893 1010 viewport.x = 0;
7894 1010 viewport.y = 0;
7895
7896 // draw the map
7897 1010 BITMAP* screen_bmp = create_bitmap_ex(8, 256, 176);
7898 1010 combotile_add_x = 256;
7899 1010 combotile_add_y = 0;
7900 1010 bool classic_draw = get_qr(qr_CLASSIC_DRAWING_ORDER);
7901
2/2
✓ Branch 0 taken 8080 times.
✓ Branch 1 taken 1010 times.
9090 for(int32_t y=0; y<8; y++)
7902 {
7903
2/2
✓ Branch 0 taken 8080 times.
✓ Branch 1 taken 129280 times.
137360 for(int32_t x=0; x<16; x++)
7904 {
7905
2/2
✓ Branch 0 taken 47360 times.
✓ Branch 1 taken 81920 times.
129280 if (!displayOnMap(x, y))
7906 81920 continue;
7907
7908 47360 int screen = map_scr_xy_to_index(x, y);
7909 47360 auto scrs = loadscr2(screen);
7910 47360 mapscr* scr = &scrs[0];
7911
2/4
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 47360 times.
✗ Branch 3 not taken.
47360 if (!scr->is_valid())
7912 continue;
7913
7914 screen_handles_t screen_handles;
7915
2/2
✓ Branch 0 taken 47360 times.
✓ Branch 1 taken 331520 times.
378880 for (int i = 0; i <= 6; i++)
7916
3/4
✓ Branch 0 taken 331520 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 114582 times.
✓ Branch 3 taken 216938 times.
331520 screen_handles[i] = {scr, scrs[i].is_valid() ? &scrs[i] : nullptr, screen, i};
7917
7918 47360 int xx = 0;
7919 47360 int yy = -playing_field_offset;
7920
7921
1/2
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
47360 if (!classic_draw)
7922 for (int layer = -7; layer <= -4; ++layer)
7923 do_ffc_layer(screen_bmp, layer, screen_handles[0], xx, yy);
7924
7925
1/2
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
47360 if(classic_draw)
7926 {
7927
2/2
✓ Branch 0 taken 47 times.
✓ Branch 1 taken 47313 times.
47360 if(XOR(scr->flags7&fLAYER2BG, DMaps[cur_dmap].flags&dmfLAYER2BG))
7928
1/2
✓ Branch 0 taken 47 times.
✗ Branch 1 not taken.
47 do_layer(screen_bmp, 0, screen_handles[2], xx, yy);
7929
1/2
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
47360 do_ffc_layer(screen_bmp, -2, screen_handles[0], xx, yy);
7930 47360 }
7931
7932
2/2
✓ Branch 0 taken 213 times.
✓ Branch 1 taken 47147 times.
47360 if(XOR(scr->flags7&fLAYER3BG, DMaps[cur_dmap].flags&dmfLAYER3BG))
7933
1/2
✓ Branch 0 taken 213 times.
✗ Branch 1 not taken.
213 do_layer(screen_bmp, 0, screen_handles[3], xx, yy);
7934
1/2
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
47360 do_ffc_layer(screen_bmp, -3, screen_handles[0], xx, yy);
7935
7936
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 47360 times.
47360 if(!classic_draw)
7937 {
7938 if(XOR(scr->flags7&fLAYER2BG, DMaps[cur_dmap].flags&dmfLAYER2BG))
7939 do_layer(screen_bmp, 0, screen_handles[2], xx, yy);
7940 do_ffc_layer(screen_bmp, -2, screen_handles[0], xx, yy);
7941 do_ffc_layer(screen_bmp, -1, screen_handles[0], xx, yy);
7942 }
7943
7944
2/4
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 47360 times.
✗ Branch 3 not taken.
47360 if(lenscheck(scr,0)) putscr(scr, screen_bmp, 0, 0);
7945
1/2
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
47360 do_ffc_layer(screen_bmp, 0, screen_handles[0], xx, yy);
7946
1/2
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
47360 do_layer(screen_bmp, 0, screen_handles[1], xx, yy);
7947
1/2
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
47360 do_ffc_layer(screen_bmp, 1, screen_handles[0], xx, yy);
7948
7949
2/2
✓ Branch 0 taken 47313 times.
✓ Branch 1 taken 47 times.
47360 if(!XOR((scr->flags7&fLAYER2BG), DMaps[cur_dmap].flags&dmfLAYER2BG))
7950 {
7951
1/2
✓ Branch 0 taken 47313 times.
✗ Branch 1 not taken.
47313 do_layer(screen_bmp, 0, screen_handles[2], xx, yy);
7952
1/2
✓ Branch 0 taken 47313 times.
✗ Branch 1 not taken.
47313 do_ffc_layer(screen_bmp, 2, screen_handles[0], xx, yy);
7953 47313 }
7954
7955
1/2
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
47360 putscrdoors(scr, screen_bmp, xx, yy);
7956
2/2
✓ Branch 0 taken 43358 times.
✓ Branch 1 taken 4002 times.
47360 if (get_qr(qr_PUSHBLOCK_SPRITE_LAYER))
7957 {
7958
1/2
✓ Branch 0 taken 43358 times.
✗ Branch 1 not taken.
43358 do_layer(screen_bmp, -2, screen_handles[0], xx, yy);
7959
2/2
✓ Branch 0 taken 3462 times.
✓ Branch 1 taken 39896 times.
43358 if(get_qr(qr_PUSHBLOCK_LAYER_1_2))
7960 {
7961
1/2
✓ Branch 0 taken 3462 times.
✗ Branch 1 not taken.
3462 do_layer(screen_bmp,-2, screen_handles[1], xx, yy);
7962
1/2
✓ Branch 0 taken 3462 times.
✗ Branch 1 not taken.
3462 do_layer(screen_bmp,-2, screen_handles[2], xx, yy);
7963 3462 }
7964 43358 }
7965
7966
2/2
✓ Branch 0 taken 47147 times.
✓ Branch 1 taken 213 times.
47360 if(!XOR((scr->flags7&fLAYER3BG), DMaps[cur_dmap].flags&dmfLAYER3BG))
7967 {
7968
1/2
✓ Branch 0 taken 47147 times.
✗ Branch 1 not taken.
47147 do_layer(screen_bmp, 0, screen_handles[3], xx, yy);
7969
1/2
✓ Branch 0 taken 47147 times.
✗ Branch 1 not taken.
47147 do_ffc_layer(screen_bmp, 3, screen_handles[0], xx, yy);
7970 47147 }
7971
7972
1/2
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
47360 do_layer(screen_bmp, 0, screen_handles[4], xx, yy);
7973
1/2
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
47360 do_ffc_layer(screen_bmp, 4, screen_handles[0], xx, yy);
7974
1/2
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
47360 do_layer(screen_bmp, -1, screen_handles[0], xx, yy);
7975
2/2
✓ Branch 0 taken 7464 times.
✓ Branch 1 taken 39896 times.
47360 if(get_qr(qr_OVERHEAD_COMBOS_L1_L2))
7976 {
7977
1/2
✓ Branch 0 taken 7464 times.
✗ Branch 1 not taken.
7464 do_layer(screen_bmp,-1, screen_handles[1], xx, yy);
7978
1/2
✓ Branch 0 taken 7464 times.
✗ Branch 1 not taken.
7464 do_layer(screen_bmp,-1, screen_handles[2], xx, yy);
7979 7464 }
7980
1/2
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
47360 do_layer(screen_bmp, 0, screen_handles[5], xx, yy);
7981
1/2
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
47360 do_ffc_layer(screen_bmp, 5, screen_handles[0], xx, yy);
7982
3/4
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1680 times.
✓ Branch 3 taken 45680 times.
47360 if(replay_version_check(40))
7983
1/2
✓ Branch 0 taken 1680 times.
✗ Branch 1 not taken.
1680 do_ffc_layer(screen_bmp, -1000, screen_handles[0], xx, yy);
7984
1/2
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
47360 do_layer(screen_bmp, 0, screen_handles[6], xx, yy);
7985
1/2
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
47360 do_ffc_layer(screen_bmp, 6, screen_handles[0], xx, yy);
7986
1/2
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
47360 do_ffc_layer(screen_bmp, 7, screen_handles[0], xx, yy);
7987
7988
1/2
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
47360 stretch_blit(screen_bmp, mappic, 0, 0, 256, 176, x<<(8-mapres), (y*176)>>mapres, 256>>mapres, 176>>mapres);
7989
1/3
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✓ Branch 2 taken 47360 times.
47360 }
7990 8080 }
7991
7992 1010 viewport = prev_viewport;
7993 1010 combotile_add_x = 0;
7994 1010 combotile_add_y = 0;
7995
7996 1010 destroy_bitmap(screen_bmp);
7997 1010 clear_keybuf();
7998 1010 pause_all_sfx();
7999
8000 // view it
8001 1010 int32_t delay = 0;
8002
8003 1010 do
8004 {
8005
2/2
✓ Branch 0 taken 189085 times.
✓ Branch 1 taken 29891 times.
218976 if (replay_version_check(0, 11))
8006 29891 load_control_state();
8007
8008 218976 int32_t step = int32_t(16.0/scales[sc]);
8009 218976 step = (step>>1) + (step&1);
8010 218976 bool r = cRbtn();
8011
8012
1/2
✓ Branch 0 taken 218976 times.
✗ Branch 1 not taken.
218976 if(cLbtn())
8013 {
8014 step <<= 2;
8015 delay = 0;
8016 }
8017
8018
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 218976 times.
218976 if(r)
8019 {
8020 if(rUp())
8021 {
8022 py+=step;
8023 redraw=true;
8024 }
8025
8026 if(rDown())
8027 {
8028 py-=step;
8029 redraw=true;
8030 }
8031
8032 if(rLeft())
8033 {
8034 px+=step;
8035 redraw=true;
8036 }
8037
8038 if(rRight())
8039 {
8040 px-=step;
8041 redraw=true;
8042 }
8043 }
8044 else
8045 {
8046
2/2
✓ Branch 0 taken 203528 times.
✓ Branch 1 taken 15448 times.
218976 if(Up())
8047 {
8048 15448 py+=step;
8049 15448 redraw=true;
8050 15448 }
8051
8052
2/2
✓ Branch 0 taken 203410 times.
✓ Branch 1 taken 15566 times.
218976 if(Down())
8053 {
8054 15566 py-=step;
8055 15566 redraw=true;
8056 15566 }
8057
8058
2/2
✓ Branch 0 taken 191540 times.
✓ Branch 1 taken 27436 times.
218976 if(Left())
8059 {
8060 27436 px+=step;
8061 27436 redraw=true;
8062 27436 }
8063
8064
2/2
✓ Branch 0 taken 192194 times.
✓ Branch 1 taken 26782 times.
218976 if(Right())
8065 {
8066 26782 px-=step;
8067 26782 redraw=true;
8068 26782 }
8069 }
8070
8071
2/2
✓ Branch 0 taken 22044 times.
✓ Branch 1 taken 196932 times.
218976 if(delay)
8072 22044 --delay;
8073 else
8074 {
8075 196932 bool a = cAbtn();
8076 196932 bool b = cBbtn();
8077
8078
3/4
✓ Branch 0 taken 1786 times.
✓ Branch 1 taken 195146 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1786 times.
196932 if(a && !b)
8079 {
8080
1/2
✓ Branch 0 taken 1786 times.
✗ Branch 1 not taken.
1786 sc=zc_min(sc+1,16);
8081 1786 delay=8;
8082 1786 redraw=true;
8083 1786 }
8084
8085
3/4
✓ Branch 0 taken 972 times.
✓ Branch 1 taken 195960 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 972 times.
196932 if(b && !a)
8086 {
8087
2/2
✓ Branch 0 taken 971 times.
✓ Branch 1 taken 1 times.
972 sc=zc_max(sc-1,0);
8088 972 delay=8;
8089 972 redraw=true;
8090 972 }
8091 }
8092
8093
2/2
✓ Branch 0 taken 218965 times.
✓ Branch 1 taken 11 times.
218976 if(rPbtn())
8094 11 --view_map_show_mode;
8095
8096 218976 px = vbound(px,-4096,4096);
8097 218976 py = vbound(py,-1408,1408);
8098
8099 218976 double scale = scales[sc];
8100
8101
2/2
✓ Branch 0 taken 75341 times.
✓ Branch 1 taken 143635 times.
218976 if(!redraw)
8102 {
8103 143635 blit(scrollbuf_old,framebuf,256,0,0,0,256,232);
8104 143635 }
8105 else
8106 {
8107 75341 clear_to_color(framebuf,BLACK);
8108 150682 stretch_blit(mappic,framebuf,0,0,mappic->w,mappic->h,
8109 75341 int32_t(256+(int64_t(px)-mappic->w)*scale)/2,int32_t(224+(int64_t(py)-mappic->h)*scale)/2,
8110 75341 int32_t(mappic->w*scale),int32_t(mappic->h*scale));
8111
8112 75341 blit(framebuf,scrollbuf_old,0,0,256,0,256,232);
8113 75341 redraw=false;
8114 }
8115
8116 218976 int32_t x = int32_t(256+(px-((2048-int64_t(lx))*2))*scale)/2;
8117 218976 int32_t y = int32_t(224+(py-((704-int64_t(ly))*2))*scale)/2;
8118
8119
2/2
✓ Branch 0 taken 7466 times.
✓ Branch 1 taken 211510 times.
218976 if(view_map_show_mode&1)
8120 {
8121 211510 line(framebuf,x-7,y-7,x+7,y+7,(frame&3)+252);
8122 211510 line(framebuf,x+7,y-7,x-7,y+7,(frame&3)+252);
8123 211510 }
8124
8125
3/4
✓ Branch 0 taken 5600 times.
✓ Branch 1 taken 213376 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 5600 times.
218976 if(view_map_show_mode&2 || r)
8126 213376 textprintf_ex(framebuf,font,224,216,WHITE,BLACK,"%1.2f",scale);
8127
8128
1/2
✓ Branch 0 taken 218976 times.
✗ Branch 1 not taken.
218976 if(r)
8129 {
8130 textprintf_ex(framebuf,font,0,208,WHITE,BLACK,"m: %d %d",px,py);
8131 textprintf_ex(framebuf,font,0,216,WHITE,BLACK,"x: %d %d",x,y);
8132 }
8133
8134 218976 advanceframe(false, false);
8135
2/2
✓ Branch 0 taken 29891 times.
✓ Branch 1 taken 189085 times.
218976 if (replay_version_check(11))
8136 189085 load_control_state();
8137
8138
2/2
✓ Branch 0 taken 217967 times.
✓ Branch 1 taken 1009 times.
218976 if (getInput(btnS, INPUT_PRESS | INPUT_IGNORE_DISABLE))
8139 1009 done = true;
8140
8141
2/2
✓ Branch 0 taken 217966 times.
✓ Branch 1 taken 1010 times.
437952 }
8142
2/2
✓ Branch 0 taken 1009 times.
✓ Branch 1 taken 217967 times.
218976 while(!done && !Quit);
8143
8144 1010 ViewingMap = false;
8145 1010 destroy_bitmap(mappic);
8146 1010 resume_all_sfx();
8147 1010 }
8148
8149 1112 int32_t onViewMap()
8150 {
8151
4/6
✓ Branch 0 taken 1112 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1112 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 102 times.
✓ Branch 5 taken 1010 times.
1112 if(Playing && cur_screen<128 && DMaps[cur_dmap].flags&dmfVIEWMAP)
8152 {
8153 1010 clear_to_color(framebuf,BLACK);
8154 1010 textout_centre_ex(framebuf,font,"Drawing map...",128,108,WHITE,BLACK);
8155 1010 advanceframe(true);
8156 1010 ViewMap();
8157 1010 }
8158
8159 1112 return D_O_K;
8160 }
8161
8162 38948858 bool isGrassType(int32_t type)
8163 {
8164
2/2
✓ Branch 0 taken 38190745 times.
✓ Branch 1 taken 758113 times.
38948858 switch(type)
8165 {
8166 case cTALLGRASS:
8167 case cTALLGRASSNEXT:
8168 case cTALLGRASSTOUCHY:
8169 758113 return true;
8170 }
8171
8172 38190745 return false;
8173 38948858 }
8174
8175 25672 bool isFlowersType(int32_t type)
8176 {
8177
2/2
✓ Branch 0 taken 21332 times.
✓ Branch 1 taken 4340 times.
25672 switch(type)
8178 {
8179 case cFLOWERS:
8180 case cFLOWERSTOUCHY:
8181 4340 return true;
8182 }
8183
8184 21332 return false;
8185 25672 }
8186
8187 bool isGenericType(int32_t type)
8188 {
8189 switch(type)
8190 {
8191 case cTRIGGERGENERIC:
8192 return true;
8193 }
8194
8195 return false;
8196 }
8197
8198 30978 bool isBushType(int32_t type)
8199 {
8200
2/2
✓ Branch 0 taken 25672 times.
✓ Branch 1 taken 5306 times.
30978 switch(type)
8201 {
8202 case cBUSH:
8203 case cBUSHNEXT:
8204 case cBUSHTOUCHY:
8205 case cBUSHNEXTTOUCHY:
8206
8207 5306 return true;
8208 }
8209
8210 25672 return false;
8211 30978 }
8212
8213 bool isSlashType(int32_t type)
8214 {
8215 switch(type)
8216 {
8217 case cSLASH:
8218 case cSLASHITEM:
8219 case cSLASHTOUCHY:
8220 case cSLASHITEMTOUCHY:
8221 case cSLASHNEXT:
8222 case cSLASHNEXTITEM:
8223 case cSLASHNEXTTOUCHY:
8224 case cSLASHNEXTITEMTOUCHY:
8225 return true;
8226 }
8227
8228 return false;
8229 }
8230
8231 18151 bool isCuttableNextType(int32_t type)
8232 {
8233
2/2
✓ Branch 0 taken 9830 times.
✓ Branch 1 taken 8321 times.
18151 switch(type)
8234 {
8235 case cSLASHNEXT:
8236 case cSLASHNEXTITEM:
8237 case cTALLGRASSNEXT:
8238 case cBUSHNEXT:
8239 case cSLASHNEXTTOUCHY:
8240 case cSLASHNEXTITEMTOUCHY:
8241 case cBUSHNEXTTOUCHY:
8242 8321 return true;
8243 }
8244
8245 9830 return false;
8246 18151 }
8247
8248 20007 bool isTouchyType(int32_t type)
8249 {
8250
2/2
✓ Branch 0 taken 8508 times.
✓ Branch 1 taken 11499 times.
20007 switch(type)
8251 {
8252 case cSLASHTOUCHY:
8253 case cSLASHITEMTOUCHY:
8254 case cBUSHTOUCHY:
8255 case cFLOWERSTOUCHY:
8256 case cTALLGRASSTOUCHY:
8257 case cSLASHNEXTTOUCHY:
8258 case cSLASHNEXTITEMTOUCHY:
8259 case cBUSHNEXTTOUCHY:
8260 11499 return true;
8261 }
8262
8263 8508 return false;
8264 20007 }
8265
8266 38867500 bool isCuttableType(int32_t type)
8267 {
8268
2/2
✓ Branch 0 taken 38414469 times.
✓ Branch 1 taken 453031 times.
38867500 switch(type)
8269 {
8270 case cSLASH:
8271 case cSLASHITEM:
8272 case cBUSH:
8273 case cFLOWERS:
8274 case cTALLGRASS:
8275 case cTALLGRASSNEXT:
8276 case cSLASHNEXT:
8277 case cSLASHNEXTITEM:
8278 case cBUSHNEXT:
8279
8280 case cSLASHTOUCHY:
8281 case cSLASHITEMTOUCHY:
8282 case cBUSHTOUCHY:
8283 case cFLOWERSTOUCHY:
8284 case cTALLGRASSTOUCHY:
8285 case cSLASHNEXTTOUCHY:
8286 case cSLASHNEXTITEMTOUCHY:
8287 case cBUSHNEXTTOUCHY:
8288 453031 return true;
8289 }
8290
8291 38414469 return false;
8292 38867500 }
8293
8294 19783 bool isCuttableItemType(int32_t type)
8295 {
8296
2/2
✓ Branch 0 taken 452 times.
✓ Branch 1 taken 19331 times.
19783 switch(type)
8297 {
8298 case cSLASHITEM:
8299 case cBUSH:
8300 case cFLOWERS:
8301 case cTALLGRASS:
8302 case cTALLGRASSNEXT:
8303 case cSLASHNEXTITEM:
8304 case cBUSHNEXT:
8305
8306 case cSLASHITEMTOUCHY:
8307 case cBUSHTOUCHY:
8308 case cFLOWERSTOUCHY:
8309 case cTALLGRASSTOUCHY:
8310 case cSLASHNEXTITEMTOUCHY:
8311 case cBUSHNEXTTOUCHY:
8312 19331 return true;
8313 }
8314
8315 452 return false;
8316 19783 }
8317
8318 69 bool is_push(mapscr* m, int32_t pos)
8319 {
8320
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 69 times.
69 if(is_push_flag(m->sflag[pos]))
8321 return true;
8322 69 newcombo const& cmb = combobuf[m->data[pos]];
8323
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 69 times.
69 if(is_push_flag(cmb.flag))
8324 return true;
8325
2/2
✓ Branch 0 taken 14 times.
✓ Branch 1 taken 55 times.
69 if(cmb.type == cPUSHBLOCK)
8326 14 return true;
8327
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 55 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
55 if(cmb.type == cSWITCHHOOK && (cmb.usrflags&cflag7))
8328 return true; //Counts as 'pushblock' flag
8329 55 return false;
8330 69 }
8331
8332 427 static std::map<int, screen_state_t> screen_states;
8333
8334 37530 std::map<int, screen_state_t>& get_screen_states()
8335 {
8336 37530 return screen_states;
8337 }
8338
8339 45808821 screen_state_t& get_screen_state(int screen)
8340 {
8341 45808821 return screen_states[screen];
8342 }
8343
8344 608 void clear_screen_states()
8345 {
8346 608 screen_states.clear();
8347 608 }
8348
8349 1597 void screen_item_set_state(int screen, ScreenItemState state)
8350 {
8351 1597 get_screen_state(screen).item_state = state;
8352 1597 }
8353
8354 557168 void mark_visited(int screen)
8355 {
8356
2/2
✓ Branch 0 taken 475 times.
✓ Branch 1 taken 556693 times.
557168 if (screen < 0x80)
8357 {
8358
2/2
✓ Branch 0 taken 96919 times.
✓ Branch 1 taken 459774 times.
556693 if(DMaps[cur_dmap].flags&dmfVIEWMAP)
8359 459774 game->maps[mapind(cur_map, screen)] |= mVISITED;
8360
8361 556693 markBmap(-1, screen);
8362 556693 }
8363 557168 }
8364